码迷,mamicode.com
首页 > 编程语言 > 详细

【剑指offer】面试题51:数组中的逆序对

时间:2019-03-23 22:42:03      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:dex   ret   closed   src   void   变形   private   因此   面试题   

题目

* 面试题51:数组中的逆序对
* 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
* 输入一个数组,求出这个数组中的逆序对的总数P。
* 并将P对1000000007取模的结果输出。 即输出P%1000000007

思路

1、暴力 ,时间复杂度O(n^2)

2、归并排序的思路 :时间复杂度O(nlogn)

* (1) 先将数组分成两半,递归分别计算左半边的逆序对数目leftCnt 和右半边的逆序对数目rightCnt
* (2)再计算合并之后新增的逆序对数目cnt

注意:
* left + right + cnt 有可能超过int,因此中间结果用long存储,最后再转化为int

代码

技术图片
 1 public class P51 {
 2      // 归并排序 的变形
 3     private long mergeSort(int[] datas, int[] copy, int start, int end){
 4         if(start == end) return 0;
 5         int mid = (start + end)/2;
 6         long leftCnt = mergeSort(datas, copy, start, mid)%1000000007;// 左边的逆序对数目
 7         long rightCnt = mergeSort(datas, copy, mid+1, end)%1000000007; // 右边的逆序对数目
 8         
 9         long cnt = 0;    // 合并之后,新增的逆序对数目
10         int index = start;    // copy数组的下标
11         int i = start;    // 左半边 数组起始下标
12         int j = mid+1;    // 右半边 数组起始下标
13         
14         // 该变量记录当左半边某个数datas[i]插入copy数组中,右半边已经插入copy数组中的数目
15         int rightSmallICnt = 0;    
16         
17         // 合并数组,合并的时候计算逆序对数目
18         while(i<=mid && j<=end){
19             if(datas[i]<=datas[j]){
20                 copy[index++] = datas[i];
21                 i++;
22                 cnt += rightSmallICnt;
23             }else{
24                 copy[index++] = datas[j];
25                 j++;
26                 rightSmallICnt++;    // 记录右半边数组中右多少个元素 已经插入到copy数组中 
27             }
28         }
29         if(i>mid){
30             while(j<=end){
31                 copy[index++] = datas[j++];    
32             }
33         }else{
34             while(i<=mid){
35                 copy[index++] = datas[i++];
36                 cnt += rightSmallICnt;
37             }
38         }
39         
40         // 复制回原数组 
41         for(int k=start;k<=end;++k) datas[k] = copy[k];
42         return (leftCnt + rightCnt + cnt)%1000000007;
43     }
44     
45     // 统计逆序对数目
46     public int InversePairs(int [] array) {
47         if(array==null || array.length<=1) return 0;    // 对输入数据进行处理
48         int[] copy = new int[array.length];                // 辅助数组
49         return (int)mergeSort(array, copy, 0, array.length-1);
50     }
51     
52     // 测试
53     public static void main(String[] args) {
54         int[] array = new int[]{5,6,7,8, 1, 2, 3, 4};
55         int ans = new P51().InversePairs(array);
56         System.out.println(ans);
57     }
58 }
View Code

 

【剑指offer】面试题51:数组中的逆序对

标签:dex   ret   closed   src   void   变形   private   因此   面试题   

原文地址:https://www.cnblogs.com/chsobin/p/10585656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!