剑指Offer35:数组中的逆序对(Java)

***参考 1. 新竹六月的博客:https://www.cnblogs.com/coffy/p/5896541.html

   2. 努力学习的宵夜的博客:https://www.cnblogs.com/xiaoyebula/p/12045554.html***

解题思路:

\(\color{#fa163f}{逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量;}\)
采用分治的思想,利用归并排序的方法计算数组中的逆序对。与归并排序不同的是从右往左遍历,这样计算逆序对方便。
还有就是计算过中大于1000000007的结果和最终结果要取模。

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

java代码:

public class Solution {
   public static int InversePairs(int[] array){
    if(array==null||array.length==0){
        return 0;
    }
    return Inversepairs(array,0,array.length-1);
    }
     public static int Inversepairs(int []arr,int left,int right){
        if(left>=right){
            return 0;
        }
        int mid =(left+right)/2;
        int leftcount=Inversepairs(arr,left,mid);
        int rightcount=Inversepairs(arr,mid+1,right);
        int count=InversePairsCore(arr,left,right,mid);
        return (leftcount+rightcount+count)%1000000007;
    }
    private static int InversePairsCore(int[] arr, int left, int right, int mid) {
        int i,j,k;
        int [] temp=new int[right-left+1];
        i=mid;
        j=right;
        k=temp.length-1;
        int sum=0;
       while(i>=left&&j>=mid+1){
           if(arr[i]>arr[j]){
               temp[k--]=arr[i--];
               sum+=j-mid;
               if(sum>=1000000007)//数值过大求余
               {
                   sum%=1000000007;
               }
           }
           else {
               temp[k--]=arr[j--];
           }
       }
       while(i>=left){
           temp[k--]=arr[i--];
       }
       while(j>mid){
           temp[k--]=arr[j--];
       }
       i=left;
       for(k=0;k<temp.length;k++){
           arr[i++]=temp[k];
       }
       return sum;
    }
}
posted @ 2020-01-18 15:49  31楼下小黑  阅读(143)  评论(0编辑  收藏  举报