剑指Offer第二十四题:数组中的逆序对(归并排序的应用)

题目

 

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

思路

本题可以通过改进归并算法实现,参考如下归并排序(Java)。其中唯一的区别就是在进行排序的时候进行统计,如果第一个子数组中的数字大于第二个数组中的数字,则构成逆序对,并且逆序对的数目等于第二个子数组中剩余数字的个数。

代码如下

 

 1 package javaTest;
 2 
 3 public class Main{
 4     
 5     static int P;
 6 
 7     public static void main(String[] args) {
 8         int a[]= {1,2,3,4,5,6,7,0};
 9         
10         System.out.println(InversePairs(a));
11     
12     }
13     
14     /*
15      * 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成
16      * 一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对
17      * 1000000007取模的结果输出。 即输出P%1000000007
18      */
19     public static int InversePairs(int [] array) {
20         P=0;
21         int end=array.length-1;
22         if(array!=null)
23             mergeDown(array, 0, end);
24         return P;
25     }
26     
27     public static void mergeDown(int []array,int start,int end) {
28         if(start>=end)
29             return;
30         
31         int mid=(end+start)/2;
32         mergeDown(array, start, mid);
33         mergeDown(array, mid+1, end);
34         
35         marge(array, start,mid, end);
36     }
37     
38     public static void marge(int []array,int start,int mid,int end) {
39         
40         int newArray[]=new int[end-start+1];
41 
42         int i=start;
43         int j=mid+1;
44         int k=0;
45         
46         while(i<=mid&&j<=end) {
47             if(array[i]>array[j]) {
48                 
49                 newArray[k++]=array[j++];
50                 
51                 P+=(mid-i+1);
52                 P%=1000000007;
53             }else {
54                 newArray[k++]=array[i++];
55             }
56         }
57         
58         while(i<=mid) {
59             newArray[k++]=array[i++];
60             
61         }
62         while(j<=end) {
63             newArray[k++]=array[j++];
64         }
65         
66         for(i=0;i<k;i++) {
67             array[start+i]=newArray[i];
68         }
69         newArray=null;
70     }
71     
72 
73     /*
74      * 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成
75      * 一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对
76      * 1000000007取模的结果输出。 即输出P%1000000007
77      */
78 
79 }

 

 

 

转载于:https://www.cnblogs.com/yangdagaoge/articles/10058045.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值