剑指Offer35:数组中的逆序对
Posted blog-cpc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指Offer35:数组中的逆序对相关的知识,希望对你有一定的参考价值。
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5
题解:归并排序
1 //统计逆序对的个数 2 private static int cnt; 3 public static int InversePairs01(int[] array) { 4 if(array.length != 0){ 5 divide(array,0,array.length-1); 6 } 7 return cnt; 8 } 9 //归并排序的分治---分 10 private static void divide(int[] arr,int start,int end){ 11 //递归的终止条件 12 if(start >= end) { 13 return; 14 } 15 //计算中间值,注意溢出 16 int mid = start + (end - start)/2; 17 18 //递归分 19 divide(arr,start,mid); 20 divide(arr,mid+1,end); 21 //治 22 merge(arr,start,mid,end); 23 } 24 25 private static void merge(int[] arr,int start,int mid,int end){ 26 int[] temp = new int[end-start+1]; 27 //存一下变量 28 int i=start,j=mid+1,k=0; 29 //下面就开始两两进行比较,若前面的数大于后面的数,就构成逆序对 30 while(i<=mid && j<=end){ 31 //若前面小于后面,直接存进去,并且移动前面数所在的数组的指针即可 32 if(arr[i] <= arr[j]){ 33 temp[k++] = arr[i++]; 34 }else{ 35 temp[k++] = arr[j++]; 36 //a[i]>a[j]了,那么这一次,从a[i]开始到a[mid]必定都是大于这个a[j]的,因为此时分治的两边已经是各自有序了 37 cnt = (cnt+mid-i+1)%1000000007; 38 } 39 } 40 //各自还有剩余的没比完,直接赋值即可 41 while(i<=mid){ 42 temp[k++] = arr[i++]; 43 } 44 while(j<=end){ 45 temp[k++] = arr[j++]; 46 } 47 //覆盖原数组 48 for (k = 0; k < temp.length; k++) { 49 arr[start + k] = temp[k]; 50 } 51 }
1 public static int InversePairs(int[] array) { 2 if(array.length==0){ 3 return 0; 4 } 5 int len=array.length; 6 int count=0; 7 for(int i=0;i<len;i++){ 8 for(int j=0;j<len-i-1;j++){ 9 if(array[j+1]<array[j]){ 10 int temp=array[j]; 11 array[j]=array[j+1]; 12 array[j+1]=temp; 13 count++; 14 } 15 } 16 } 17 return count%1000000007; 18 }
测试:
1 public static void main(String[] args) { 2 int[] arr={1,2,3,4,5,6,7,0}; 3 int pairs = InversePairs01(arr); 4 System.out.println(pairs); 5 } 6 输出:7
以上是关于剑指Offer35:数组中的逆序对的主要内容,如果未能解决你的问题,请参考以下文章