本题源自leetcode 493
-------------------------------------------------------------------------------------
反向对:我们称(i,j)是一个重要的反向对,如果i <j且nums [i]> 2 * nums [j]。
思路:利用归并排序的思想。先求出左半部分和右半部分的反向对个数。在归并计算
代码:
int reversePairs(vector<int>& nums) {
if(nums.size()<2)
return 0;
return sortAndCount(nums.begin(),nums.end());
}
int sortAndCount(vector<int>::iterator begin,vector<int>::iterator end){
if(end - begin < 2)
return 0;
auto mid=begin+(end-begin)/2;
int count=sortAndCount(begin,mid)+sortAndCount(mid,end);
for(auto i=begin,j=mid; i != mid; i++){
while(j!=end && *i > 2L * *j) //long型
j++;
count += j-mid;
}
inplace_merge(begin,mid,end); //归并排序
return count;
}
代码:
int count;
int reversePairs(vector<int>& nums) {
if(nums.size()<2)
return 0;
count = 0;
mergeSort(nums,0,nums.size()-1);
return count;
}
void mergeSort(vector<int>& nums,int start,int end){
if(start == end)
return;
int mid = (start + end) >> 1;
mergeSort(nums,start,mid);
mergeSort(nums,mid+1,end);
checkCount(nums,start,mid,end);
}
void checkCount(vector<int>& nums,int start,int mid,int end){
int l=start;
int r=mid+1;
while(l <= mid && r <= end){
if(nums[l] > nums[r] * 2L){
count += mid-l+1;
r++;
}else{
l++;
}
}
sort(nums.begin()+start,nums.begin()+end+1);
}