这个题主要用到了排序算法中的 mergeSort, 通过 mergeSort(分治法)过程中来发现我们的逆序对
class Solution {
public:
int reversePairs(vector<int>& nums) {
vector<int> temp(nums.size());
return mergeSort(0, nums.size()-1, nums, temp);
}
int mergeSort(int l, int r, vector<int>& nums, vector<int>& temp){
// 先写出递归的结束条件, 当左数组与右数组是一个的时候, 停止, 返回0, 因为不存在逆序对
if(l>=r) return 0;
// 分, 我们需要找到 中间点(分点)
int m = (l + r)/2;
// 记录左子数组的后代的res总和, 记录右子数组的后代的res总和(只包括后代, 不包括 左右子数组)
int res = mergeSort(l, m, nums, temp) + mergeSort(m+1, r, nums, temp);
// 在 mergeSort(从小到大, 左子数组和右子树组都是排好序的) 该层的 左数组 与 右数组 顺便统计下 该层的 res
// 1. 首先我们需要先复制copy一份temp, 用来存放原始值, 而nums则是排序好之后的
for(int k= l; k<=r; k++){
temp[k] = nums[k];
}
// 2. 建立左右子数组的两个指针 i ,j 分别指向左右子数组的开头
int i = l;
int j = m+1;
for(int k=l; k<=r; k++) {
// 左右merge的时候, 如果左子数组都已经被添加完了, 只有右子数组剩余
if(i==m+1){
nums[k] = temp [j];
j++;
}
// 左右merge的时候, 如果右子数组都已经被添加完了, 只有左子数组剩余,那么全加入,没得可比了
// 或者, 左子数组的值 < 右子数组的值 => 不够成逆序对
else if(j == r+1 || temp[i]<=temp[j]){
nums[k] = temp[i];
i++;
}
// 左子数组的值 > 右子数组的值, mergeSort 右子树组的值的时候(同时记录一下res, 因为右边的这个值与当前剩余的左子树都构成了逆序对)
else{
nums[k] = temp[j];
j++;
res += m -i +1;
}
}
return res;
}
};