题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
样例描述
示例 1:
输入: [7,5,6,4]
输出: 5
思路
归并排序 + 分治思想
- 在归并排序的过程中统计逆序对的数量,如下是递归排序的过程
- 总共的逆序对数量等于 左边的逆序对 + 右边的逆序对 + 左右结合的时候形成的逆序对
在两边都排好序后,左边某个值如果大于右边,则该值一直到左边端点都会大于右边这个值 - 先进行左右两边的统计,在统计中间
- 递归排序要借助辅助数组


代码
class Solution {
public int reversePairs(int[] nums) {
if (nums.length <= 1) return 0;
return mergeSort(nums, 0, nums.length - 1);
}
public int mergeSort(int []nums, int l, int r) {
//只有一个数字,逆序对为0
if (l >= r) {
return 0;
}
int res = 0, k = 0;
//借助临时数组来排序
int tmp[] = new int[r - l + 1];
int mid = l + (r - l) / 2;
int i = l, j = mid + 1;
//先统计好二分的左右两边
res = mergeSort(nums, l, mid) + mergeSort(nums, mid + 1, r);
while (i <= mid && j <= r) {
if (nums[i] > nums[j]) {
tmp[k ++] = nums[j ++];
//逆序对个数
res += mid - i + 1;
}
else {
tmp[k ++] = nums[i ++];
}
}
//扫尾
while (i <= mid) {
tmp[k ++] = nums[i ++];
}
while (j <= r) {
tmp[k ++] = nums[j ++];
}
//将排好序的tmp从0开始的部分,放回到原数组[l, r]
for (i = l, j = 0; i <= r; i ++ ) {
nums[i] = tmp[j ++];
}
return res;
}
}
该博客主要介绍了如何使用Java通过归并排序解决LeetCode中的逆序对问题。作者详细解释了思路,即利用分治策略在归并排序过程中统计逆序对,并给出了相应的代码实现。

2371

被折叠的 条评论
为什么被折叠?



