// 解法一:
class Solution {
public:
// 递归定义:返回数组中索引l~r的逆序对个数
int Msort(vector<int>& nums, int l, int r)
{
if (l >= r)
return 0;
int mid = l + (r - l) / 2;
vector<int> tmp;
// 类似于树的后序遍历,先求出左右子树的逆序对个数
int res = Msort(nums, l, mid) + Msort(nums, mid + 1, r);
int i = l;
int j = mid + 1;
while (i <= mid && j <= r) {
if (nums[i] > nums[j]) {
// 待合并的两个有序数组,假设第一个数组的第i个元素大于第二个数组的第j个元素
// 那么第一个数组从i开始至末尾的元素和第二个数组的第j个元素都构成逆序对
res += mid + 1 - i;
tmp.push_back(nums[j++]);
} else {
tmp.push_back(nums[i++]);
}
}
// 将剩余元素移入tmp数组中
while (i <= mid)
tmp.push_back(nums[i++]);
while (j <= r)
tmp.push_back(nums[j++]);
copy(tmp.begin(), tmp.end(), nums.begin() + l);
return res;
}
int reversePairs(vector<int>& nums)
{
return Msort(nums, 0, nums.size() - 1);
}
};
// 解法二:简化
class Solution {
public:
int reversePairs(vector<int>& nums) {
int sz=nums.size();
return mergeSort(nums,0,sz-1);
}
int mergeSort(vector<int>& nums,int left,int right){
if(left>=right) return 0;
int mid=left+(right-left)/2;
int res=mergeSort(nums,left,mid)+mergeSort(nums,mid+1,right);
int i=left;
int j=mid+1;
while(i<=mid && j<=right){
if(nums[i]>nums[j]){
res+=mid+1-i;
j++;
}
else{
i++;
}
}
inplace_merge(nums.begin()+left,nums.begin()+mid+1,nums.begin()+right+1);
return res;
}
};