面试题36:数组中的逆序对

来源:互联网 发布:java游戏服务端开发 编辑:程序博客网 时间:2024/06/10 01:45
public class Solution {    public int InversePairs(int [] array) {        int len=array.length;        if(array==null||len==0)            return 0;        int [] copy = new int[len];        for(int i=0;i<len;i++){            copy[i]=array[i];        }        int count=InversePairs(array,copy,0,len-1);        return count;    }    public int InversePairs(int[]array,int []copy,int start,int end){         // 递归终止条件        if(start==end){            copy[start]=array[start];            return 0;        }                int midLen=(end-start)>>1;              /*        解法二:小区别        对已经统计了逆序对的数组,我们需要对其排好序,以避免在以后的统计过程中再次重复统计,        所以copy数组就是起到这个作用,当然,这里的有序只是“局部有序”,整体来看还是无序的。        既然copy数组是“有序”的,下一次就直接在这个基础上进行统计就可以,        原始数据data用来充当原来copy数组的角色来保存“更加有序”的数组,这样进行递归,        就节省了数据来回拷贝所浪费的时间。        */        int left=InversePairs(array,copy,start,start+midLen);//int left=InversePairs(copy,data,start,start+midLen);        int right=InversePairs(array,copy,start+midLen+1,end);//int left=InversePairs(copy,data,start,start+midLen);                int i=start+midLen;// 前半部分的下标        int j=end;// 后半部分的下标        int copyIndex=end;// 辅助数组copy的下标        int count=0;// 记录本次逆序对数        while((i>=start)&&(j>=start+midLen+1)){            if(array[i]>array[j]){                copy[copyIndex--]=array[i--];                count+=j-start-midLen;                if(count>1000000007)                    count%=1000000007;            }            else{                copy[copyIndex--]=array[j--];            }        }        while(i>=start){//把前一个数组中剩下的写入copy数组            copy[copyIndex--]=array[i--];        }        while(j>=start+midLen+1){//或者把后一个数组中剩下的写入copy数组,两个数组中总有一个有多余的元素            copy[copyIndex--]=array[j--];        }        //将原数组排序        for(int s=start;s<=end;s++){//这段删掉            array[s] = copy[s];        }        return (left+right+count)%1000000007;    }}