数组逆序对

来源:互联网 发布:安卓改机软件 编辑:程序博客网 时间:2024/06/18 17:54

题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4)。

最直观的解法:
最简单的想法就是遍历每一个元素,让其与后面的元素对比,如果大于则count++,但是这样的时间复杂度是o(n2)。

enter image description here

先把数组分解成两个长度为2的子数组,再把这两个子数组分解成两个长度为1的子数组。接下来一边合并相邻的子数组,一边统计逆序对的数目。在第一对长度为1的子数组{7}、{5}中7>5,因此(7,5)组成一个逆序对。同样在第二对长度为1的子数组{6},{4}中也有逆序对(6,4),由于已经统计了这两对子数组内部的逆序对,因此需要把这两对子数组进行排序,避免在之后的统计过程中重复统计

enter image description here

逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量;

 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 = InversePairsCore(array,copy,0,array.length-1);//数值过大求余        return count;    }    private int InversePairsCore(int[] array, int[] copy, int start, int end) {        if (start==end){            copy[start]=array[start];            return 0;        }        int length=(end-start)/2;        int left=InversePairsCore(copy,array,start,start+length);        int right=InversePairsCore(copy,array,start+length+1,end);        int i=start+length;        int j=end;        int indexCopy=end;        int count=0;        while (i>start&&j>=start+length+1){            if (array[i]>array[j]){                copy[indexCopy--]=array[i--];                count+=j-start-length;            }else {                copy[indexCopy--]=array[j--];            }        }        for (;i>=start;--i){            copy[indexCopy--]=array[i];        }        for (; j>=start+length+1;--j){            copy[indexCopy--]=array[j];        }        return left+right+count;    }

参考文章

  • http://www.cnblogs.com/coffy/p/5896541.html
  • http://www.cnblogs.com/yml435/p/4655472.html
0 0
原创粉丝点击