☞梦想进大厂的一只程序猿☜
☞期望毕业前力扣刷够400题☜
☞正在复习数据结构和算法☜
☞博客地址:https://www.huangliangshuai.com/☜
【2020秋招-面试题目汇总(随时更新)】
归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
一般求逆序对时,使用!!!
public int reversePairs(int[] nums) {
int len = nums.length;
if (len < 2) {
return 0; // 如果长度为1或者是0的话,则直接返回0
}
int[] temp = new int[len]; // 利用这个辅助数组来进行交换
int[] copy = new int[len]; // 我们存储一个原来的数组,这样容易看出比较性
for (int i = 0; i < len; i++) {
copy[i] = nums[i];
}
// 这里我们的边界是[0,len-1],辅助数组为temp
return reversePairs(copy, 0, len - 1, temp);
}
public int reversePairs(int[] nums, int left, int right, int[] temp) {
if (left == right) {
return 0;
}
int mid = left + (right - left) / 2;
int leftPairs = reversePairs(nums, left, mid, temp);
int rightPairs = reversePairs(nums, mid + 1, right, temp);
int crossPairs = mergeAndCount(nums, left, mid, right, temp);
return leftPairs + rightPairs + crossPairs;
}
public int mergeAndCount(int[] nums, int left, int mid, int right, int[] temp) {
for (int i = left; i <= right; i++) {
temp[i] = nums[i];
}
int i = left;
int j = mid + 1;
int count = 0;
for (int k = left; k <= right; k++) {
if (i == mid + 1) {
nums[k] = temp[i];
i++;
} else if (j == right + 1) {
nums[k] = temp[j];
j++;
} else if (temp[i] <= temp[j]) {
nums[k] = temp[i];
i++;
} else if (temp[i] > temp[j]) {
nums[k] = temp[j];
j++;
count += mid - i + 1;
}
}
return count;
}
// 手撕归并 -- 逆序对
public class Demo01 {
public int reversePairs(int[] nums) {
int len = nums.length;
if (len < 2) {
return 0; // 如果长度为1或者是0的话,则直接返回0
}
int[] temp = new int[len]; // 利用这个辅助数组来进行交换
int[] copy = new int[len]; // 我们存储一个原来的数组,这样容易看出比较性
for (int i = 0; i < len; i++) {
copy[i] = nums[i];
}
// 这里我们的边界是[0,len-1],辅助数组为temp
return reversePairs(nums, 0, len - 1, temp);
}
public int reversePairs(int[] nums, int left, int right, int[] temp) {
if (left == right) {
return 0;
}
int mid = left + (right - left) / 2;
int leftPairs = reversePairs(nums, left, mid, temp);
int rightPairs = reversePairs(nums, mid + 1, right, temp);
int crossPairs = mergeAndCount(nums, left, mid, right, temp);
return leftPairs + rightPairs + crossPairs;
}
public int mergeAndCount(int[] nums, int left, int mid, int right, int[] temp) {
for (int i = 0; i < nums.length; i++) {
temp[i] = nums[i];
}
int i = left;
int j = mid + 1;
int count = 0;
for (int k = left; k <= right; k++) {
if (i == mid + 1) {
nums[k] = temp[i];
i++;
} else if (j == right + 1) {
nums[k] = temp[j];
j++;
} else if (temp[i] <= temp[j]) {
nums[k] = temp[i];
i++;
} else if (temp[i] > temp[j]) {
nums[k] = temp[j];
j++;
count += mid - i + 1;
}
}
return count;
}
}