题目
主要就是 两个有序数组,怎么统计 (x,y)其中x>y,x在第一个数组,y在第二个数组的对数。
比如 第一个数组是[4,9],第二个数组是[2,3,5,6]
其中两个指针i,j的走向分别是:
i指向4,j指向2.
i指向4,j指向3.
i指向4,j指向5. (这个时候i应该变了,对于4来说,第二个数组小于4的个数就是5的下标-mid)。
i指向9,j指向5.
i指向9,j指向6.
所以每次在i指针要往前移动的时候,统计第二个数组里面有多少个小于 i当前指向的数。
还可将权值离散化,直接上树状数组。懒得写了。
class Solution {
public:
int *tmp,n,ans;
void cdq(int l,int r,vector<int>& q){
if(l>=r) return;//当q为空,l=0,r=-1;
int mid=(l+r)>>1;
cdq(l,mid,q),cdq(mid+1,r,q);
int i=l,j=mid+1,k=l;
//当q[i]<=a[j]:既然j从j-1变成了j,那么一定有<=i的ii使得q[ii]>q[j-1],所以q[i]>q[j-1]。
while(i<=mid&&j<=r){
if(q[i]<=q[j]) ans+=(j-(mid+1)),tmp[k++]=q[i++];
else tmp[k++]=q[j++];
}
while(i<=mid) ans+=(j-(mid+1)),tmp[k++]=q[i++];
while(j<=r) tmp[k++]=q[j++];
for(int i=l;i<=r;++i) q[i]=tmp[i];
}
int reversePairs(vector<int>& nums) {
int n=nums.size();tmp=new int[n];
cdq(0,n-1,nums);
return ans;
}
};