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

剑指offer35:数组中的逆序对

时间:2019-08-27 23:28:55      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:idt   class   dex   desc   sep   拷贝   计算   spl   思路   

1 题目描述

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

2 思路和方法

  利用归并排序的思想,先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。注意在合并两个已排序的子数组后,要更新数组。O(n*log(n))。

技术图片

 

3 C++核心代码

技术图片
 1 class Solution {
 2 public:
 3     int InversePairs(vector<int> data) {
 4         if(data.size() <= 1)
 5             return 0;
 6         int count = 0;
 7         vector<int> copy(data); // 初始化
 8         InversePairsCore(data, copy, 0, data.size()-1,count);
 9         return count;
10     }
11 
12     // 归并
13     void InversePairsCore(vector<int> &data, vector<int> &copy, int start, int end, int &count){
14         if(start>=end){
15             return;
16         }
17         int mid = (start + end) /2;
18         InversePairsCore(data,copy,start,mid,count);
19         InversePairsCore(data,copy,mid+1,end,count);
20 
21         int copyIndex = end; // 将较大数字从后往前复制到辅助数组
22         int i = mid;    // 前半段最后一个元素下标
23         int j = end;    // 后半段最后一个元素下标
24         while (i>=start && j>=mid+1) {
25             if (data[j] < data[i]){     // 逆序
26                 count += j - mid;
27                 count %= 1000000007;    // 取模防止逆序对溢出
28                 copy[copyIndex--] = data[i--];
29             } else{
30                 copy[copyIndex--] = data[j--];
31             }
32         }
33 
34         while (i>=start)
35             copy[copyIndex--] = data[i--];
36 
37         while (j>=mid+1)
38             copy[copyIndex--] = data[j--];
39 
40         for (int k = start; k <= end; ++k)
41             data[k] = copy[k];
42 
43     }
44 };
View Code

4 C++完整代码

技术图片
 1 #include<iostream>
 2 using namespace std;
 3 //数组中的逆序对
 4 long long GetMergePairsBetween(int* arr,int* copy,int start,int mid,int end)
 5 {
 6     //合并两个子数组,并计算逆序对个数
 7     int final1 = mid;//第一个数组的最后一位
 8     int final2 = end;//第二个数组的最后一位
 9     int index = end;//辅助数组的最后一位
10     long long count = 0;
11     while(final1 >= start && final2 >= mid+1)//两个数组都没有处理完
12     {
13        if(arr[final1] > arr[final2])
14        {
15            //如果第一个数组的元素大于第二个数组的任何元素,
16            //则第一个数组的元素一定大于第个数组中final2之前的所有元素
17            count += (final2 - mid);
18            //将final1处的元素拷贝至copy数组
19            //index和final1都向前移动
20            copy[index--] = arr[final1--];
21        }
22        else
23        {
24            //第一个数组的元素小于第二个数组的元素
25            //第二个数组的元素拷贝至copy数组
26            //并将index和final2前移
27            copy[index--] = arr[final2--];
28        }
29     }
30     while(final1 >= start)//第一个数组的元素没有处理完
31     {
32        copy[index--] = arr[final1--];
33     }
34     while(final2 >= mid + 1)//第一个数组的元素没有处理完
35     {
36        copy[index--] = arr[final2--];
37     }
38     for(int i = end; i > index;i--) 
39         arr[i] = copy[i];
40     return count;
41 }
42 long long GetMergePairs(int* arr,int* copy,int start,int end)
43 {
44     long long ret = 0;
45     if(start < end)
46     {
47        int mid = start + ((end - start)>>1);
48        ret += GetMergePairs(arr,copy,start,mid);
49        ret += GetMergePairs(arr,copy,mid+1,end);
50        ret += GetMergePairsBetween(arr,copy,start,mid,end);
51     }
52     return ret;
53 }
54 long long GetTotalPairs(int arr[],int n)
55 {
56     if(arr == NULL || n < 2)
57        return 0;
58     int* copy = new int[n];
59     long long sum = GetMergePairs(arr,copy,0,n-1);
60     delete[] copy;
61     return sum;
62 }
63 int main()
64 {
65     int arr[] = {7,5,6,4};
66     int ret = GetTotalPairs(arr,sizeof(arr)/sizeof(arr[0]));
67     cout<<ret<<endl;
68     system("pause");
69     return 0;
70 }
View Code

参考资料

https://blog.csdn.net/zjwreal/article/details/88769617

https://blog.csdn.net/DERRANTCM/article/details/46761051(图)

https://blog.csdn.net/peiyao456/article/details/54645952(完整代码)

 

剑指offer35:数组中的逆序对

标签:idt   class   dex   desc   sep   拷贝   计算   spl   思路   

原文地址:https://www.cnblogs.com/wxwhnu/p/11421187.html

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