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.
这个题目改进了原题的要求。
我的思路: 归并排序。不通过。
正确题解:
在递归函数中递归后,先不合并,首先处理逆序数,然后再合并。这样需要再写一个合并函数。这样的好处是在处理计数的时候不需要考虑谁先被写入copy数组。使得复杂度降低。
class Solution {
public:
int reversePairs(vector<int>& nums) {
return divide(nums,0,nums.size()-1);
}
int divide(vector<int>& nums,int start,int end){
if(start<end)
{
int mid=start+(end-start)/2;
int count=divide(nums,start,mid)+divide(nums,mid+1,end);
int j=mid+1;
for(int i=start;i<=mid;i++)
{
while(j<=end&&nums[i]>nums[j]*2LL)
{
j++;
}
count+=j-mid-1;
}
merge(nums,start,mid,end);
return count;
}
else
return 0;
}
void merge(vector<int>& A,int start,int mid,int end){
int n1=mid-start+1;
int n2=end-mid;
vector<int> left(A.begin()+start,A.begin()+mid+1);
vector<int> right(A.begin()+mid+1,A.begin()+end+1);
int i=0;
int j=0;
for(int k=start;k<=end;k++)
{
if(j>=n2||(i<n1&&left[i]<=right[j]))//有等号,目的是先把左边的尽量加入进来
{
A[k]=left[i++];
}
else
{
A[k]=right[j++];
}
}
}
};