数组中的逆序对

题目描述

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

输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

  思路:暴力法时间复杂度为O(n^2),基于归并排序的解法时间复杂度为O(nlogn)

  ps:一直纳闷为什么要输出P%1000000007而不是直接输出P,直到写完提交以后,通过率为50%,原因是我的答案竟然出现了负数,才发现int装不下,改用long,然而函数返回值又要求是int,恍然大悟P%1000000007!!!!!  嗯,一切又解释得通了,世界又变得美好了。。。

 1 class Solution {
 2 public:
 3     long Merge(int *tmp, vector<int> &data, int left, int mid, int right)
 4     {
 5         long count=0;
 6         int i, j, k;
 7         for(i=mid, j=right, k=right; i>=left && j>=mid+1; --k)
 8         {
 9             if(tmp[i]>tmp[j])
10             {
11                 count=count+j-mid;
12                 data[k]=tmp[i--];
13             }else{
14                 data[k]=tmp[j--];
15             }
16         }
17         while(i>=left)data[k--]=tmp[i--];
18         while(j>=mid+1)data[k--]=tmp[j--];
19         for(int idx=left; idx<=right; ++idx)tmp[idx]=data[idx];
20         return count;
21     }
22     long MergeSort(vector<int> &data, int *tmp, int left, int right)
23     {
24         if(left==right)
25         {
26             tmp[left]=data[left];
27             return 0;
28         }else{
29             int mid=(left+right)/2;
30             long val1=MergeSort(data, tmp, left, mid);
31             long val2=MergeSort(data, tmp, mid+1, right);
32             long val3=Merge(tmp, data, left, mid, right);
33             return val1+val2+val3;
34         }
35     }
36     int InversePairs(vector<int> data) {
37         if(data.size()<=1)return 0;
38         int *tmp=new int[data.size()];//辅助数组
39         long res=MergeSort(data, tmp, 0, data.size()-1);//归并排序
40         delete []tmp;
41         return res%1000000007;
42     }
43 };

   更规范的写法是:

 1 void Merge(vector<int> &data, int begin, int mid, int end, long long &result)
 2 {
 3     int *arr=new int[end-begin+1];
 4     int i, j, k;
 5     for(i=begin, j=mid+1, k=0; i<=mid && j<=end; ++k)
 6     {
 7         if(data[i]>data[j])
 8         {
 9             arr[k]=data[j++];
10             result=result+mid-i+1;//注意和上面不同之处
11         }else arr[k]=data[i++];
12     }
13     while(i<=mid)arr[k++]=data[i++];
14     while(j<=end)arr[k++]=data[j++];
15     for(int idx=begin; idx<=end; ++idx)data[idx]=arr[idx-begin];
16     delete []arr;
17 }
18 void MergeSort(vector<int> &data, int begin, int end, long long &result)
19 {
20     if(begin>=end)return;
21     int mid=(begin+end)/2;
22     MergeSort(data, begin, mid, result);
23     MergeSort(data, mid+1, end, result);
24     Merge(data, begin, mid, end, result);
25 }
26 int InversePairs(vector<int> data)
27 {
28     long long result=0;
29     if(data.size()==0)return result;
30     MergeSort(data, 0, data.size()-1, result);
31     return result%1000000007;
32 }

 

posted @ 2017-12-29 18:48  jeysin  阅读(120)  评论(0编辑  收藏  举报