剑指offer51 数组中的逆序对

首先题意明确一下,这个题描述的其实没那么清晰:

首先数组的顺序是不能变的,在这个数组中,位置靠前的数大于位置靠后的数,则这两个数组成一对逆序对。

比如{1,2,3,4,5,6,7,0} 中有7个逆序对。

那首先暴力解法,挨个找呗。O(n^2)。

然后参考剑指offer的借鉴归并排序的思路:(比大小的题都可以联想下可否尝试排序算法,正如最值问题都可以想下DP)

比如对{1,2,3,0}找逆序对,就把其分为两组A{1,2}和B{3,0},先在每组中找逆序对(递归),再在两组之间(A出第一个元素,B出第二个元素)找最后三者加起来:

public class Solution {
    public int InversePairs(int [] array) {
        if(array==null||array.length<1) return 0;
        
        int[] copy = new int[array.length];
        for(int i=0;i<copy.length;i++) copy[i]=array[i];
        return getInversePairs(array,copy,0,array.length-1);
    }
    private int getInversePairs(int[] array,int[] copy,int start,int end){
        if(start==end) return 0;
        int mid = (start+end)/2;
        int leftcount = getInversePairs(array,copy,start,mid);
        int rightcount = getInversePairs(array,copy,mid+1,end);
        
        int p1=mid,p2=end;
        int count=0;
        int p3=end;//copyarray index
        while(p1>=start&&p2>mid){
            if(array[p1]>array[p2]){
                count+=(p2-mid)%1000000007;
                count%=1000000007;
                copy[p3--]=array[p1];
                p1--;
            }else{
                copy[p3--]=array[p2];
                p2--;
            }
        }
        for(;p1>=start;p1--) copy[p3--]=array[p1];
        for(;p2>mid;p2--) copy[p3--]=array[p2];
        for(int i=start;i<=end;i++) array[i]=copy[i];
        return (leftcount%1000000007+rightcount%1000000007+count%1000000007)%1000000007;
    }
}

运行时间:644ms

占用内存:54304k

牛客网非要搞一个取模运算,略麻烦。不过也提醒我们在连续相加时,每次都要加上模运算。

python版思路:

# -*- coding:utf-8 -*-
class Solution:
    def InversePairs(self, data):
        # write code here
        if data is None or len(data)<1:
            return 0
        copy = data[:]
        return self.mergeSortHelper(data,copy,0,len(data)-1)
        
    def mergeSortHelper(self,data,copy,l,r):
        if l==r:
            return 0
        m = (l+r)//2
        leftcount=self.mergeSortHelper(data,copy,l,m)
        rightcount=self.mergeSortHelper(data,copy,m+1,r)
        count=0
        i=l;j=m+1;t=l 
        while i<=m and j<=r:
            if data[i]<=data[j]:
                copy[t]=data[i]
                t+=1;i+=1
             else:
                copy[t]=data[j]
                t+=1;j+=1
                count+=j-(m+1)+1
        while i<=m:
            copy[t]=data[i]
            t+=1;i+=1
            count+=r-(m+1)+1
        while j<=r:
            copy[t]=data[j]
            t+=1;j+=1
        t=l 
        while t<=r:
            nums[t]=copy[t]
            t+=1
        return leftcount+rightcount+count

 

posted @ 2019-03-01 11:26  大胖子球花  阅读(286)  评论(0)    收藏  举报