归并排序
class Solution {
// 归并排序
public void mergeSort(int[] array) {
if (array == null || array.length < 2) return ;
mergeSort(array,0,array.length - 1);
}
public void mergeSort(int[] array,int left,int right){
// 其中一段只有一个元素没有必要再分再比较,直接返回
if (right == left) return;
int mid = left + ((right - left) >> 1);
// 分别递归排序左半段和右半段,再合并在一起
mergeSort(array,left,mid);
mergeSort(array,mid + 1,right);
merge(array,left,mid,right);
}
public void merge(int[] array,int left,int mid,int right){
// 开辟一个辅助数组储存排序好的数字
int[] help = new int[right - left + 1];
// 设置两个指针分别指向左右半段的起点,i指针指向help的起点方便往help里储存数字
int p1 = left;
int p2 = mid + 1;
int i = 0;
while (p1 <= mid && p2 <= right){
help[i++] = array[p1] < array[p2] ? array[p1++] : array[p2++];
}
while (p1 <= mid){
help[i++] = array[p1++];
}
while (p2 <= right){
help[i++] = array[p2++];
}
// 最后再把help排序好的数字再挪回array中
for (int j : help) {
array[left++] = j;
}
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{1,3,4,2,5};
solution.mergeSort(nums);
System.out.println(nums);
}
}
小和问题
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。
例子:[1,3,4,2,5] 1左边比1小的数,没有;
3左边比3小的数,1;
4左边比4小的数,1、3;
2左边比2小的数,1;
5左边比5小的数,1、3、4、2;
所以小和为1+1+3+1+1+3+4+2=16
class Solution {
public int mergeSort(int[] array) {
if (array == null || array.length < 2) return 0;
return mergeSort(array,0,array.length - 1);
}
public int mergeSort(int[] array,int left,int right){
// 其中一段只有一个元素没有必要再分再比较,直接返回
if (right == left) return 0;
int mid = left + ((right - left) >> 1);
// 分别递归排序左半段和右半段,再合并在一起
int leftSum = mergeSort(array,left,mid);
int rightSum = mergeSort(array,mid + 1,right);
return leftSum + rightSum + merge(array,left,mid,right);
}
public int merge(int[] array,int left,int mid,int right){
// 开辟一个辅助数组储存排序好的数字
int[] help = new int[right - left + 1];
// 设置两个指针分别指向左右半段的起点,i指针指向help的起点方便往help里储存数字
int p1 = left;
int p2 = mid + 1;
int i = 0;
int result = 0;
while (p1 <= mid && p2 <= right){
result += array[p1] < array[p2] ? (right - p2 + 1) * array[p1] : 0;
help[i++] = array[p1] < array[p2] ? array[p1++] : array[p2++];
}
while (p1 <= mid){
help[i++] = array[p1++];
}
while (p2 <= right){
help[i++] = array[p2++];
}
// 最后再把help排序好的数字再挪回array中
for (int j : help) {
array[left++] = j;
}
return result;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{1,3,4,2,5};
System.out.println(solution.mergeSort(nums));
}
}
逆序队问题
在一个数组中,左边的数如果比右边的数大,则这两个数构成一个逆序对,请打印所有逆序对。
同上
荷兰国旗问题
给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
返回值含义: 一定会返回一个长度为2的数组,等于区域的左边界和右边界(也就是相等区域的边界范围 )
class Solution {
public int[] partition(int[] arr, int left, int right, int num) {
// less为小于num区的边界,more为大于num的边界,left当做遍历数组的指针
int less = left - 1;
int more = right + 1;
while (left < more){
if (arr[left] < num){
swap(arr,left++,++less);
}else if (arr[left] > num){
swap(arr,--more,left);
}else {
left++;
}
}
return new int[]{less + 1,more - 1};
}
public void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{3,5,0,3,4,5,2,6,9,6,1};
solution.partition(nums,0,nums.length - 1,5);
System.out.println(solution.partition(nums,0,nums.length - 1,5));
}
}
快速排序
class Solution {
public void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
public void quickSort(int[] arr, int l, int r) {
if (l < r) {
int[] p = partition(arr, l, r);
quickSort(arr, l, p[0]);
quickSort(arr, p[1], r);
}
}
public int[] partition(int[] arr, int left, int right) {
// less为小于num区的边界,more为大于num的边界,left当做遍历数组的指针
int less = left - 1;
int more = right + 1;
while (left < more){
if (arr[left] < arr[right]){
swap(arr,left++,++less);
}else if (arr[left] > arr[right]){
swap(arr,--more,left);
}else {
left++;
}
}
return new int[]{less,more};
}
public void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{3,5,0,3,4,5,2,6,9,6,1};
solution.quickSort(nums);
System.out.println(nums.toString());
}
}