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