归并求解逆序对c++
时间: 2025-05-09 20:21:41 浏览: 27
### 使用 C++ 和归并排序算法计算数组中的逆序对数量
要使用归并排序算法计算数组中的逆序对数量,可以基于归并排序的思想,在合并两个子数组的过程中统计跨组的逆序对。以下是详细的实现方式:
#### 实现逻辑
1. **分治法**:将数组分为两部分 `[l, mid]` 和 `[mid+1, r]`,分别递归地计算这两部分内部的逆序对。
2. **合并阶段**:在合并过程中,当左侧子数组的一个元素大于右侧子数组的一个元素时,则说明存在逆序对。具体来说,如果 `arr[i] > arr[j]` (其中 `i ∈ [l, mid], j ∈ [mid+1, r]`),那么从索引 `i` 到 `mid` 的所有元素都会与当前的 `j` 构成逆序对。
#### 代码实现
以下是一个完整的 C++ 实现示例:
```cpp
#include <iostream>
#include <vector>
using namespace std;
long long mergeAndCount(vector<int>& nums, vector<int>& temp, int l, int m, int r) {
int i = l; // 左侧子数组起始位置
int j = m + 1; // 右侧子数组起始位置
int k = l; // 合并后的数组起始位置
long long count = 0;
while (i <= m && j <= r) {
if (nums[i] <= nums[j]) { // 如果左侧小于等于右侧,无逆序对
temp[k++] = nums[i++];
} else { // 如果左侧大于右侧,构成逆序对
temp[k++] = nums[j++];
count += (m - i + 1); // 计算跨越的逆序对数目
}
}
// 复制剩余的左半部分
while (i <= m) {
temp[k++] = nums[i++];
}
// 复制剩余的右半部分
while (j <= r) {
temp[k++] = nums[j++];
}
// 将临时数组的内容复制回原数组
for (int p = l; p <= r; ++p) {
nums[p] = temp[p];
}
return count;
}
long long mergeSortAndCount(vector<int>& nums, vector<int>& temp, int l, int r) {
long long count = 0;
if (l < r) {
int m = l + (r - l) / 2;
count += mergeSortAndCount(nums, temp, l, m);
count += mergeSortAndCount(nums, temp, m + 1, r);
count += mergeAndCount(nums, temp, l, m, r);
}
return count;
}
long long inversePairs(vector<int> nums) {
int n = nums.size();
vector<int> temp(n, 0);
return mergeSortAndCount(nums, temp, 0, n - 1);
}
int main() {
vector<int> nums = {7, 5, 6, 4};
cout << "Number of Inverse Pairs: " << inversePairs(nums) << endl;
return 0;
}
```
#### 关键点解析
- 在函数 `mergeAndCount` 中,每当发现 `nums[i] > nums[j]` 时,会增加 `(m - i + 1)` 对逆序对[^1]。
- 函数 `mergeSortAndCount` 是递归调用的核心,负责分解问题并对每层的结果进行累加。
- 整体的时间复杂度为 \(O(n \log n)\),空间复杂度为 \(O(n)\)[^3]。
---
###
阅读全文
相关推荐


















