剑指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

浙公网安备 33010602011771号