求逆序对的问题可以采用归并排序或者BIT数据结构进行求解,这里给出归并排序的做法,核心是在递归的时候,使用双指针维护左边i和右边j的位置,保证j是最小的a[i] <= 2 * a[j], 那么所有小于j的下标都是对答案的贡献
红色即为贡献
class Solution {
public:
vector<int> w;
int reversePairs(vector<int>& nums) {
return merge(nums, 0, nums.size() - 1);
}
int merge(vector<int> &a, int l, int r) {
if (l >= r) return 0;
int mid = l + r >> 1;
int ans = 0;
ans += merge(a, l, mid);
ans += merge(a, mid + 1, r);
for (int i = l, j = mid + 1; i <= mid; i++) {
while (j <= r && a[j] * 2ll < a[i]) j++;
ans += j - (mid + 1);
}
w.clear();
int i = l, j = mid + 1;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) w.push_back(a[i++]);
else w.push_back(a[j++]);
}
while (i <= mid) w.push_back(a[i++]);
while (j <= r) w.push_back(a[j++]);
for (int i = l, j = 0; j < w.size(); i++, j++) a[i] = w[j];
return ans;
}
};