来源于我的博客
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
输入例子:
1,2,3,4,5,6,7,0
输出例子:
7
分治思想求解
这题直接暴力求解会超时的,主要的思想是利用归并排序n*logn的时间复杂度,在merge归并的时候计算逆序对个数,例如:
5 7 | 3 6
合并时,ai=0和aj=mid+1比较,发现3比5小,由于每个数组都是递增的,所以3的逆序对个数即为前面从i开始的数字个数(mid+1-i)
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.size()<2)
return 0;
cnt=0;
MergeSort(data,0,data.size()-1);
return cnt%1000000007;
}
long long cnt=0;
void Merge(vector<int> &a,int start,int mid,int end){
int i,j;
i=start;
j=mid+1;
vector<int> res;
while(i<=mid&&j<=end){
if(a[i]<=a[j]){
res.push_back(a[i++]);
}else{
res.push_back(a[j++]);
cnt += mid-i+1;
cnt %= 1000000007;
}
}
while(i<=mid){
res.push_back(a[i++]);
}
while(j<=end){
res.push_back(a[j++]);
}
for(int i=0;i<res.size();i++){
a[start+i]=res[i];
}
}
void MergeSort(vector<int> &a,int start,int end){
if(start<end){
int mid=(start+end)/2;
MergeSort(a, start, mid);
MergeSort(a, mid+1, end);
Merge(a, start, mid, end);
}
}
};