剑35—数组中的逆序对

本文介绍了一种高效计算数组中逆序对总数的方法,并通过一个具体的Java实现示例进行了解释。该算法利用归并排序的思想,在排序过程中计算逆序对的数量,并考虑了大数处理,确保计算结果不会溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

示例1
输入
1,2,3,4,5,6,7,0
输出
7

代码如下:

public class Solution
{
    public int InversePairs(int [] array) {
        if(array==null||array.length==0)
            return 0;
        //复制数组
        int []copy=new int[array.length];
        for (int i = 0; i <array.length ; i++) {
            copy[i]=array[i];
        }
        int count=InversePairs(array,copy,0,array.length-1);
        return count;

    }
    private int InversePairs(int[]array,int[]copy,int low,int high) {
        if(low==high)
            return 0;
        int mid=(low+high)>>1;

        int leftCount=InversePairs(array,copy,low,mid)%1000000007;
        int rightCount=InversePairs(array,copy,mid+1,high)%1000000007;

        int count=0;
        int i=mid;
        int j=high;
        int lowCopy=high;

        while(i>=low&&j>mid)
        {
            if(array[i]>array[j])
            {
                count+=j-mid; //前面最小的大于后面最大的,则逆序对是后面个数j-(mid+1)+1
                copy[lowCopy--]=array[i--];//说明array[i]是最大的,将这放在新数组
                if(count>=1000000007){
                    count%=1000000007;
                }
            }
            else{
                copy[lowCopy--]=array[j--];//说明此时array[j]是最大的,复制到辅助数组中
            }
        }
        //边界处理?
        for(;i>=low;i--){
            copy[lowCopy--]=array[i];
        }
        for (;j >mid;j--) {
            copy[lowCopy--]=array[j];
        }

        //将拷贝回原数组
        for (int k = low; k <=high; k++) {
            array[k]=copy[k];
        }
        return (leftCount+rightCount+count)%1000000007;

    }

    public static void main(String[] args) {
        Solution solution=new Solution();
        int[]array={1,2,3,4,5,6,7,0};
        System.out.println(solution.InversePairs(array));

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值