题目描述
参考:https://blog.csdn.net/qq_38984851/article/details/83242429
思路
具体思路参考文中引用博客,其核心在于:每次归并之后的合并操作时进行处理,假设目前数组情形如下:
i指向6,j指向2,此时由于[l, m]和[m+1, r]都是有序的,所以此时[i…m]的所有元素和[j]都组成逆序对,具体个数即为m-i+1个,如果需要保存具体数对,只需将[i…m]的元素和[j]位置的元素组合即可!
代码
class Solution{
public:
long sum = 0;
vector<vector<int>> pairs;
void merge(vector<int> &vec, int l, int m, int r){
vector<int> temp(r - l + 1, 0);
int i = l, j = m + 1, k = 0;
while(i <= m && j <= r){
if(vec[i] > vec[j]){ //逆序对形成条
sum += m - i + 1;
//在此处保存逆序对, 因为在此处vec[i] > vec[j]则可以说明vec[i...m]均大于vec[j],它们都是逆序对,所以才会出现个数为m-i+1
int jj = i;
while(jj <= m){
pairs.push_back(vector<int>({vec[jj++], vec[j]}));
}
temp[k++] = vec[j++];
}else{
temp[k++] = vec[i++];
}
}
while(i <= m){
temp[k++] = vec[i++];
}
while(j <= r){
temp[k++] = vec[j++];
}
k = 0;
while(l <= r){
vec[l++] = temp[k++];
}
}
void mergeSort(vector<int> &vec, int l, int r){
if(l < r){
int mid = (l + r) >> 1;
mergeSort(vec, l, mid);
mergeSort(vec, mid + 1, r);
merge(vec, l, mid, r);
}
}
//求所有逆序对
int InversePairs(vector<int> data){
int l = 0, r = vec.size() - 1;
mergeSort(data, l, r);
// 打印具体的逆序对
for(auto each : pairs){
cout << "(" << each.front() << ", " << each.back() <<")"<<endl;
}
return sum % 1000000007;
}
};
merge中的语句还可以简练,因为temp临时变量存在的目的是将vec中的[l…r]元素进行,有序化,那么可不可以在原地进行,进而去掉temp。