题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
算法:
可以使用归并排序的思路,将时间复杂度从
n2−>nlogn
具体思路:
大的在前边的数字对称为逆序对,在归并排序的过程中,如果前边数组的数大于后边数组的数,则就是逆序对。将逆序对个数累加,并组成新的合并降序数组,继续递归归并排序。
class Solution {
public:
long countRes ;
int InversePairs(vector<int> data) {
countRes = 0;
if(data.size() == 0)
return 0;
MergeSort(data,0,data.size()-1);
return countRes%1000000007 ;
}
//归并降序排序
void MergeSort(vector<int>& data,int first,int end){
if(first < end){
int mid = (first + end)/2;
MergeSort(data,first,mid);
MergeSort(data,mid+1,end);
vector<int> tmp;
MergeArray(data,first,mid,end,tmp);
}
}
void MergeArray(vector<int>& data,int first,int mid,int end,vector<int> tmp){
int i = first;int m = mid;
int j = mid + 1;int n = end;
while(i<=m && j<=n){
if(data[i] > data[j]){
tmp.push_back(data[i++]);
//如果前边数组的数大于后边数组的数,那么就是逆序对。
//因为后边数组也是将序排列的,需要加上后边的所有数字,都能组成逆序对。
countRes += n - j + 1;
}
else{
tmp.push_back(data[j++]);
}
}
while(i<=m)
tmp.push_back(data[i++]);
while (j<=n)
tmp.push_back(data[j++]);
//更新data数组
int k = 0;
for (int i = first; i <= end &&k<tmp.size(); i++)
data[i] = tmp[k++];
}
};