美文网首页
剑指 offer 笔记 35 | 数组中的逆序对

剑指 offer 笔记 35 | 数组中的逆序对

作者: ProudLin | 来源:发表于2019-11-09 23:00 被阅读0次

    题目描述
    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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

    思路分析
    首先得理解什么是逆序对?
    例如在数组{7,5,6,4}中,一共有 5 个逆序对,分别是{7,6}、{7,5}、{7,4}、{6,4}、{5,4}。

    实际上是一个分治问题,不断将数组一分为二,直到数组中只有两个元素,统计逆序对个数,分别排序后进行合并,merge 的时候计算合并的两个数组间的逆序对个数。

    所以会用到「归并排序」这个算法:
    [A,B] 中的逆序对 = [A]的逆序对+[B]中的逆序对+将A,B混排在一起的逆序对。

    解释说明:

    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 = InversePairsCore(array,copy,0,array.length-1);//数值过大求余
            return count;
             
        }
        private int InversePairsCore(int[] array,int[] copy,int low,int high)
        {
            if(low==high)
            {
                return 0;
            }
            int mid = (low+high)>>1;
            int leftCount = InversePairsCore(array,copy,low,mid)%1000000007;
            int rightCount = InversePairsCore(array,copy,mid+1,high)%1000000007;
            int count = 0;
            int i=mid;
            int j=high;
            int locCopy = high;
            while(i>=low&&j>mid)
            {
                if(array[i]>array[j])
                {
                    count += j-mid;
                    copy[locCopy--] = array[i--];
                    if(count>=1000000007)//数值过大求余
                    {
                        count%=1000000007;
                    }
                }
                else
                {
                    copy[locCopy--] = array[j--];
                }
            }
            for(;i>=low;i--)
            {
                copy[locCopy--]=array[i];
            }
            for(;j>mid;j--)
            {
                copy[locCopy--]=array[j];
            }
            for(int s=low;s<=high;s++)
            {
                array[s] = copy[s];
            }
            return (leftCount+rightCount+count)%1000000007;
        }
    }
    

    链接:https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5?f=discussion
    来源:牛客网

    相关文章

      网友评论

          本文标题:剑指 offer 笔记 35 | 数组中的逆序对

          本文链接:https://www.haomeiwen.com/subject/wvgdbctx.html