Given an array nums
, we call (i, j)
an important reverse pair if i < j
and nums[i] > 2*nums[j]
.
You need to return the number of important reverse pairs in the given array.
Example1:
Input: [1,3,2,3,1] Output: 2
Example2:
Input: [2,4,3,5,1] Output: 3
Note:
- The length of the given array will not exceed
50,000
. - All the numbers in the input array are in the range of 32-bit integer.
Subscribe to see which companies asked this question.
给一个序列,要求求出其中“重要反转对”的个数。如果用暴力的方法对每个数nums[i]都找一遍符合nums[i] > 2*nums[j],要运算n*(n-1)/2次。参考discuss的答案。。用merge_sort的想法来实现。对当前的序列二分,对每个子序列,求出在每个子序列中“重要反转对”的个数(递归实现),然后对每个子序列用merge_sort排序。这样得到两个子序列各自的
的和,再加上第一个子序列中的数和第二个子序列中的数作比较符合要求的总数(因为已经排好序所以容易实现),就能得到“重要反转对”的个数
,还有排序后的子序列,然后两个子序列各自的
“重要反转对”的个数
当前序列的“
,最后将两个子序列merge_sort并返回当前结果。要注意的是比较重要反转对”的个数
nums[i] > 2*nums[j]
时,会出现2*nums[j]
溢出int的范围,所以要注意转换成long long。
代码:
class Solution
{
public:
int reversePairs(vector<int>& nums)
{
return merge_count(nums.begin(), nums.end());
}
private:
int merge_count(vector<int>::iterator begin, vector<int>::iterator end)
{
if(end - begin <= 1) return 0;
auto mid = begin + (end - begin) / 2;
int cnt = merge_count(begin, mid) + merge_count(mid, end);
for(auto i = begin, j = mid; i != mid; ++i)
{
while(j != end && *i > 2L * *j)
{
++j;
}
cnt += (j - mid);
}
inplace_merge(begin, mid, end);
return cnt;
}
};