题目描述
分析
很典型的归并排序题目
利用归并排序在 merge 过程中两个区间有序的特点,进行逆序对统计
算法
归并排序
过程
统计的过程在归并排序过程中进行,因此如果只有一个元素不进行统计,返回 0
对左,右区间分别统计,加和,然后在两区间合并过程中再进行统计
原理
eg:[1, 2, 6, 7], [3, 4]
当左区间指向 6 的时候,实际上可以明白的是 6,7 两个元素都是逆序对的组成部分(和 3 组成),因此统计的数字应当加上的长度就是 mid - p1 + 1,也就是 p1 指针到最后一个元素的闭区间部分
代码
/**
* @param {number[]} nums
* @return {number}
*/
var reversePairs = function (nums) {
return countResults(nums, 0, nums.length - 1)
}
function countResults(nums, l, r) {
if (l >= r) return 0
const temp = [],
mid = (l + r) >> 1
let ans = 0,
p1 = l,
p2 = mid + 1,
k = 0
ans += countResults(nums, l, mid)
ans += countResults(nums, mid + 1, r)
while (p1 <= mid || p2 <= r) {
if (p2 > r || (p1 <= mid && nums[p1] <= nums[p2])) {
temp[k++] = nums[p1++]
} else {
temp[k++] = nums[p2++]
ans += mid - p1 + 1
}
}
for (let i = l; i <= r; i++) {
nums[i] = temp[i - l]
}
return ans
}