本题思路:在递归函数中递归后,先不合并,首先处理逆序数,然后再合并。这样需要再写一个合并函数。这样的好处是在处理计数的时候不需要考虑谁先被写入copy数组。使得复杂度降低。
归并排序看这个
第一种:二分法,妥妥垫底 1500ms 差点超时
class Solution {
public:
int reversePairs(vector<int>& nums) {
long cnt = 0;
vector<long> trans;
if (nums.size() == 0)
return cnt;
trans.push_back((long)2 * nums[nums.size() - 1]);
for (int i = nums.size() - 2; i >= 0; i--) {
auto it = lower_bound(trans.begin(), trans.end(), nums[i]);
cnt += it - trans.begin();
it = lower_bound(trans.begin(), trans.end(), (long)2 * nums[i]);
trans.insert(it, (long)2 * nums[i]);
}
return cnt;
}
};
第二种:归并排序,160ms
class Solution {
public:
int reversePairs(vector<int>& nums) {
int n = nums.size();
if (n <= 0)
return 0;
ans = new double[n];
res = 0;
sort(nums, 0, n - 1);
return res;
}
double* ans;
int res;
void sort(vector<int>& nums, int l, int r){
if (r <= l)
return;
int m = (l + r) >> 1;
sort(nums, l, m);
sort(nums, m + 1, r);
int i = l, j = m + 1;
while(j <= r){
while(i <= m && (double)nums[i] / 2 <= nums[j])
i++;
res += m - i + 1;
j++;
}
merge(nums, l, m, r);
}
void merge(vector<int>& nums, int l, int m, int r){
for (int i = l; i <= r; i++)
ans[i] = nums[i];
int i = l, j = m + 1;
int k = l,n = r;
while(i <= m && j <= n){
if (ans[i] <= ans[j])
nums[k++] = ans[i++];
else
nums[k++] = ans[j++];
}
while(i <= m)
nums[k++] = ans[i++];
while(j <= n)
nums[k++] = ans[j++];
}
};