1 题目
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2 Java
2.1 方法一(归并)
其实本题就是求,将数组排序,需要交换多少对连续元素(不能跨两三个元素交换,一个一个来)
冒泡、插入都可以做,但超时
希尔由于出现大跨度交换,不行
归并排序虽然有大跨度交换,但每次都是在子问题中,不影响相邻子问题的逆序组数
class Solution {
int ans = 0;
public int reversePairs(int[] nums) {
mergeSort(nums);
return ans;
}
public int[] mergeSort(int[] nums){
if(nums.length <= 1) return nums;
int mid = nums.length / 2;
int[] left = Arrays.copyOfRange(nums, 0, mid);
int[] right = Arrays.copyOfRange(nums, mid, nums.length);
return merge(mergeSort(left), mergeSort(right));
}
public int[] merge(int[] left, int[] right){
int l = 0, r = 0, lMax = left.length, rMax = right.length;
int[] arrs = new int[lMax + rMax];
while(l < lMax || r < rMax){
if(l < lMax && r < rMax){
if(left[l] <= right[r]) arrs[l + r] = left[l++];
else if(left[l] > right[r]){
arrs[l + r] = right[r++];
ans += lMax - l; // 比起原始归并排序,唯一添加的代码
}
}
else if(l < lMax) arrs[l + r] = left[l++];
else if(r < rMax) arrs[l + r] = right[r++];
}
return arrs;
}
}