剑指 Offer 51. 数组中的逆序对 (一维cdq/树状数组模板)

题目
在这里插入图片描述
主要就是 两个有序数组,怎么统计 (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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值