在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
/**
* https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
* 剑指 Offer 51. 数组中的逆序对
* ————————————————————————————————————————————————————————————————————————————
* 题目描述:
* 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
* 输入一个数组,求出这个数组中的逆序对的总数。
* ————————————————————————————————————————————————————————————————————————————
* keyword:归并排序
* 题解:
* ————————————————————————————————————————————————————————————————————————————
* 笔记:
* ————————————————————————————————————————————————————————————————————————————
* 相关题目:
* ————————————————————————————————————————————————————————————————————————————
*/
public class Offer51_reversePairs {
public static int reversePairs(int[] nums) {
return mergeSort(nums, 0, nums.length - 1);
}
private static int mergeSort(int[] arr, int l, int r) {
if (l >= r) {
return 0;
}
int mid = l + ((r - l) >> 1);
int count = mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r);
int tempArrSize = r - l + 1;
int[] tempArr = new int[tempArrSize];
int i = l;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= r) {
if (arr[i] > arr[j]) {
count += mid - i + 1;
tempArr[k] = arr[j];
++j;
} else {
tempArr[k] = arr[i];
++i;
}
++k;
}
while (i <= mid) {
tempArr[k] = arr[i];
++i;
++k;
}
while (j <= r) {
tempArr[k] = arr[j];
++j;
++k;
}
for (int m = 0; m < tempArr.length; m++) {
arr[m + l] = tempArr[m];
}
return count;
}
}