这一题和剑指 offer上的那题很想,唯一的区别就是这里需要大于两倍。
一开始我以为这会导致那个归并的方法不能用。后来想一想能用,但是怎么算逆序有出了幺蛾子,比如用二分来算。但是对于两个已排序的数组,它们这种大小关系都是连续的,所以可以用双指针来做,这样就豁然开朗了。
class Solution {
public:
int reversePairs(vector<int>& nums) {
int sz = nums.size();
if (sz < 2)
return 0;
vector<int> aux(sz);
int retCnt = 0;
mergeSort(nums, 0, sz-1, aux, retCnt);
return retCnt;
}
private:
void mergeSort(vector<int>& nums, int beg, int end, vector<int>& aux, int& retCnt) {
if (beg >= end)
return;
int mid = beg + (end - beg) / 2;
mergeSort(nums, beg, mid, aux, retCnt);
mergeSort(nums, mid+1, end, aux, retCnt);
int i = beg, j = mid + 1;
while (j <= end) {
while (i <= mid && (long long)nums[i] <= 2 * (long long)nums[j])
++i;
retCnt += (mid - i + 1);
++j;
}
merge(nums, beg, mid, end, aux);
}
void merge(vector<int>& nums, int beg, int mid, int end, vector<int>& aux) {
int i = beg, j = mid+1;
int k = beg;
while (i <= mid || j <= end) {
if (i > mid)
aux[k++] = nums[j++];
else if (j > end)
aux[k++] = nums[i++];
else if (nums[i] <= nums[j])
aux[k++] = nums[i++];
else
aux[k++] = nums[j++];
}
for (int m = beg; m <= end; ++m)
nums[m] = aux[m];
}
};
``