版权声明:所有的博客仅仅作为个人笔记使用!!!!!!! https://blog.csdn.net/qq_35976351/article/details/83007607
问题描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
求解思路
归并排序的方法求解,这样获得的复杂度是 。思路如下:假设左右两侧区间是排好序并且已经统计完逆序对个数的序列,那么对这两个区间进行归并。假设左边的区间此时的下标移动到i,右边区间下标移动到j,左侧区间从l开始,右侧区间从m开始,整个区间到r结束,都是左闭右开的;那么,此时对于R[j]来说,逆序对的个数是m-l-i个,只有L[i]后边的比它大。这样递归地求解,并把左右两侧的逆序对和归并的逆序对加起来,就是总的逆序对的个数。
注意一个坑:要用长整型long
表示,否则会超出int
的范围无法通过!!!!题目对p取模暗示了这一点。。。。。MMP,wa了好几次发现的。。。。。。
AC代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.empty()) {
return 0;
}
return MergeSort(data, 0, data.size()) % 1000000007;
}
long Merge(vector<int>& vec, int l, int m, int r) {
long num = 0;
vector<int>L;
L.assign(vec.begin() + l, vec.begin() + m);
vector<int>R;
R.assign(vec.begin() + m, vec.begin() + r);
int i = 0, j = 0, t = l;
while(i < m - l && j < r - m) {
if(R[j] < L[i]) {
num += m - l - i;
vec[t] = R[j];
++j;
} else {
vec[t] = L[i];
++i;
}
++t;
}
while(i < m - l) {
vec[t] = L[i];
++t;
++i;
}
while(j < r - m) {
vec[t] = R[j];
++t;
++j;
}
return num;
}
long MergeSort(vector<int>&vec, int l, int r) {
if(l >= r - 1) { // 只有一个元素
return 0;
}
int m = l + (r - l) / 2;
long n1 = MergeSort(vec, l, m);
long n2 = MergeSort(vec, m, r);
long n3 = Merge(vec, l, m, r);
return n1 + n2 + n3;
}
};
int main() {
Solution so;
vector<int>vec{10, 1, 2, 3, 4, 5, 6, 7, 0};
cout << so.InversePairs(vec);
return 0;
}