注:此题与327题很相似。
解法一:分治
直接考虑,如果是两个有序数组,O(N)能不能做,用单指针明显可以,同327题。故直接分治解决。
typedef long long ll;
class Solution {
public:
void msort(vector<int>& nums, int& sum, int l, int r)
{
if(l == r)return;
int mid = l + (r-l)/2;
msort(nums, sum, l, mid);
msort(nums, sum, mid+1, r);
int p1 = mid+1;
for(int p0=l;p0<=mid;p0++)
{
while(p1 <= r && nums[p0] > 2*(ll)nums[p1])p1++;
sum += p1-mid-1;
}
inplace_merge(nums.begin()+l, nums.begin()+mid+1, nums.begin()+r+1);
}
int reversePairs(vector<int>& nums) {
int ret = 0;
msort(nums, ret, 0, nums.size()-1);
return ret;
}
};
解法二:平衡二叉树
由于要满足顺序关系,依然,分治能做,平衡二叉树也能做。
typedef long long ll;
class Solution {
public:
int reversePairs(vector<int>& nums) {
int ret = 0;
multiset<ll> s;
for(auto num: nums)
{
ll target = (ll)num*2 + 1;
auto it = s.lower_bound(target);
ret += distance(it, s.end());
s.insert(num);
}
return ret;
}
};
leetcode超时,原因是迭代器相减要消耗O(N)时间,multiset的迭代器不支持随机访问。故若想实现,必须用pbds的tree自己做二分。
其他解法:线段树、树状数组
可看327题解法。是一样的。