在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4] 输出: 5
限制:
0 <= 数组长度 <= 50000
Related Topics
归并,基本思路李姐
归并过程可以把代码的注释打开看下,以实际数据来解释说明下
归并数组: [7, 6, 5, 4, 3] [32, 11, 8, 2, 1]
idxL:0
idxR:3
2
idxL:1
idxR:3
2
idxL:2
idxR:3
2
idxL:3
idxR:3
2
idxL:4
idxR:3
2
归并结果: [32, 11, 8, 7, 6, 5, 4, 3, 2, 1]
-----
以上数组A[7, 6, 5, 4, 3]
、B[32, 11, 8, 2, 1]
- 合并的时候,A的第0个
7
小于B的第0个32
,结果第一位插入32
,第二位11
同样,第三位8
同样 - A下标0的数字
7
大于B下标3的数字2
,此时7
和后面的[2, 1]
形成逆序对,逆序对个数加2 6
同样和后面的[2, 1]
形成逆序对,逆序对个数加2[5, 4, 3]
也一样,逆序对分别加2- 而在这之前的A数组内部的逆序对,在最开始之前的时候做归并排序
归并数组: [7] [5]
idxL:0
idxR:0
1
归并结果: [7, 5]
-----
以及归并数组: [7, 5] [6]
和归并数组: [4] [3]
,再将这两个合并归并数组: [7, 6, 5] [4, 3]
,得到结果[7, 6, 5, 4, 3]
,在这个过程中已经计算过了
class Solution {
int count = 0;
public int reversePairs(int[] nums) {
sort(nums);
return count;
}
public int[] sort(int[] nums){
if (nums.length<2){
return nums;
}
int[] right = new int[nums.length/2];
int[] left = new int[nums.length - right.length];
System.arraycopy(nums,0,left,0,left.length);
System.arraycopy(nums,left.length,right,0,right.length);
left = sort(left);
right = sort(right);
return mergeArray(left,right);
}
public int[] mergeArray(int[] left, int[] right) {
if (right.length==0){
return left;
}
// System.out.println("归并数组: "+Arrays.toString(left) +" "+ Arrays.toString(right));
int[] arr = new int[left.length + right.length];
int idx = -1;
int idxL = 0;
int idxR = 0;
while (++idx < arr.length){
if (idxL<left.length && (idxR>= right.length || left[idxL] > right[idxR])){
arr[idx] = left[idxL];
idxL++;
count += right.length-idxR;
// System.out.println(right.length-idxR);
}else{
arr[idx] = right[idxR];
idxR++;
}
}
// System.out.println("归并结果: "+Arrays.toString(arr));
// System.out.println("-----");
return arr;
}
}
发表评论