题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
思路:
利用归并排序的思想,在merge时,若 left[ i ] > right[ j ],由于左右均为有序,故 left [ i ...left.size-1] 均大于 right[ j ],可直接统计。算法复杂度O(nlogn)。
代码:
语言:C++,已通过牛课网在线测试。
class Solution {
private:
long long count = 0;
public:
int InversePairs(vector<int> data) {
if(data.size()) mergesort(data, 0, data.size() - 1);
return count % 1000000007;
}
//将一个数组进行归并排序
void mergesort(vector<int> &data, int left, int right){
if(left >= right) return;//要有等号
int mid = (left + right) >> 1;
mergesort(data, left, mid);
mergesort(data, mid + 1, right);
merge(data, left, mid, right);
}
//将两个有序序列合并
void merge(vector<int> &data, int left, int mid, int right){
vector<int> tmp;
int i = left, j = mid + 1;
while(i <= mid && j <= right){
if(data[i] <= data[j]){
tmp.push_back(data[i++]);
}
else{//统计逆序对
count += mid - i + 1;
tmp.push_back(data[j++]);
}
}
while(i <= mid) tmp.push_back(data[i++]);
while(j <= right) tmp.push_back(data[j++]);
//将tmp[0,..size-1]复制回data[left,...right]
for(int k = 0; k < tmp.size(); k++) data[left + k] = tmp[k];
}
};