解法一 归并排序
速度比较慢
class Solution {
public:
int merge(vector<int>& num,int l, int r){
if(l>=r) return 0;
int mid = l+r>>1;//r右移一位
int res = merge(num,l,mid)+merge(num,mid+1,r);
int i= l,j=mid+1;
vector<int> temp;
while (i<=mid && j <=r)
{
if (num[i] <= num[j]) temp.push_back(num[i++]);//i++先赋值再运算
else
{
temp.push_back(num[j++]);
res = res + mid-i+1;//此时已经排序,从小到大
}
}
while (i<=mid) temp.push_back(num[i++]);
while (j<=r) temp.push_back(num[j++]);//可能i,j不能在上一层遍历中遍历完全
i=l;
for (auto x:temp)
{
num[i] = x;
i++;
}
return res;
}
int reversePairs(vector<int>& nums) {
return merge(nums,0,nums.size()-1);
}
};
解法二 归并排序改进
优化掉过多的while
class Solution {
public:
int reversePairs(vector<int>& nums) {
vector<int> tmp(nums.size());
return mergeSort(0, nums.size() - 1, nums, tmp);
}
private:
int mergeSort(int l, int r, vector<int>& nums, vector<int>& tmp) {
// 终止条件
if (l >= r) return 0;
// 递归划分
int m = (l + r) / 2;
int res = mergeSort(l, m, nums, tmp) + mergeSort(m + 1, r, nums, tmp);
// 合并阶段
int i = l, j = m + 1;
for (int k = l; k <= r; k++)
tmp[k] = nums[k];
for (int k = l; k <= r; k++) {
if (i == m + 1)
nums[k] = tmp[j++];
else if (j == r + 1 || tmp[i] <= tmp[j])
nums[k] = tmp[i++];
else {
nums[k] = tmp[j++];
res += m - i + 1; // 统计逆序对
}
}
return res;
}
};