数组中的逆序对

思路:使用归并排序思想,将array分为两部分,分别计算count,然后两部分归并统计。

需要注意的点:

1. 归并统计过程,可以使用两种思路:(1)对于第一部分每一个值,从第二部分二分查找比它大的元素下标,下标之前的元素数量计入统计值;(2)从两个部分的末尾开始比对(数组升序),对于第一部分的一个元素,若在第二部分中顺序找到比它小的元素,则该元素及其之前的元素数量计入统计值。

2.归并过程中仍然需要排序,也就是说,提取某一部分的逆序对统计值后,该部分就已经有序。

3.题目提示了数组容量,因此在统计值变化的步骤,都需要对统计值取模,避免int型的count统计量被加爆。

代码:

public int mergeCount(int[] array,int start1,int end1,int start2,int end2){
        if(array==null||array.length==0||end1<start1||end2<start2) return 0;
        //变量区
        int totalLength=(end1-start1+1)+(end2-start2+1);
        int[] bufStore=new int[totalLength];
        int pointer1=end1,pointer2=end2,pointer3=totalLength-1;
        int count=0;

        //归并排序
        while(pointer1>=start1&&pointer2>=start2){
            while(pointer1>=start1&&array[pointer1]>array[pointer2]){
                bufStore[pointer3--]=array[pointer1--];
                //若array[pointer1]>array[pointer2],统计逆序数量
                count+=(pointer2-start2+1);
                count%=1000000007;//注意取模
            }
            if(pointer1<start1) break;
            while(pointer2>=start2&&array[pointer1]<=array[pointer2]){
                bufStore[pointer3--]=array[pointer2--];
            }
            if(pointer2<start2) break;
        }

        if(pointer1>=start1) {
            for(int i=pointer1;i>=start1;i--){
                bufStore[pointer3--]=array[i];
            }
        }
        if(pointer2>=start2) {
            for(int i=pointer2;i>=start2;i--){
                bufStore[pointer3--]=array[i];
            }
        }

        pointer1=start1;pointer2=start2;
        for(int i=0;i<totalLength;i++){
            if(i<(end1-start1+1)) array[pointer1++]=bufStore[i];
            if(i>=(end1-start1+1)) array[pointer2++]=bufStore[i];
        }
        return count;
    }
    public int mergeSortCount(int [] array,int start,int end) {
        if(array==null||array.length==0||start>=end) return 0;
        int middle=(start+end)/2;
        int leftPartCount=mergeSortCount(array,start,middle)%1000000007;
        int rightPartCount=mergeSortCount(array,middle+1,end)%1000000007;
        int combineCount=mergeCount(array,start,middle,middle+1,end)%1000000007;
        return (leftPartCount+rightPartCount+combineCount)%1000000007;
    }

    public int InversePairs(int [] array) {
        if(array==null||array.length==0) return 0;
        return mergeSortCount(array,0,array.length-1)%1000000007;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值