【算法】求一个数组中的逆序对数

来源:互联网 发布:统计不重复数据个数 编辑:程序博客网 时间:2024/05/17 08:27

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
分析:
最简单的解法就是遍历数组中的每一个元素,让每个元素与后面的元素对比,如果大于则逆序对数count++,但是时间复杂度是o(n2)
比较好的思路是利用分治的思想:
     先求前面半部分数组的逆序数,再求后面半部分数组的逆序数,然后求前面一半数组比后面一半数组中大的数的个数,最终求得三部分加和,如果过大进行取余运算。
代码如下:
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 = InversePairsNum(array,copy,0,array.length-1);//数值过大求余        return count;             }    private int InversePairsNum(int[] array,int[] copy,int low,int high)    {        if(low==high)        {            return 0;        }        int mid = (low+high)>>1;        int leftCount = InversePairsNum(array,copy,low,mid)%1000000007;        int rightCount = InversePairsNum(array,copy,mid+1,high)%1000000007;        int count = 0;        int i=mid;//递归后,array的前部分和后部分已经有序。并且前部分和逆序数和后部分的逆序数都已经求出。        int j=high;        int currentIndex = high;        while(i>=low&&j>mid)//从两部分的末尾开始,在两部分都没有走到头的情况下,归并前后两部分到copy数组中。        {            if(array[i]>array[j])//取两部分的大者,放入copy末尾。            {                count += j-mid;//因为前后部分数组都有序,则说明j位置之前的元素都小于i位置                copy[currentIndex--] = array[i--];//坐标分别前移                if(count>=1000000007)//数值过大求余                {                    count%=1000000007;                }            }            else            {                copy[currentIndex--] = array[j--];//取两部分的大者,放入copy末尾。            }        }        while(i>=low)//前部分如果有剩余,依次放入copy中        {            copy[currentIndex--]=array[i];            i--;        }        while(j>mid)//后部分如果有剩余,依次放入copy中        {            copy[currentIndex--]=array[j];            i--;        }        for(int s=low;s<=high;s++)        {            array[s] = copy[s];//copy有序数组赋值放入array中        }        return (leftCount+rightCount+count)%1000000007;//返回结果    }}


原创粉丝点击