1. 逆序对问题概述
逆序对(Inversion Pair)是算法领域中一个经典问题,它衡量了一个序列的无序程度。在金融交易分析、基因序列比对、推荐系统等实际场景中都有重要应用。简单来说,在一个数组中,如果存在下标 i < j 且 nums[i] > nums[j],那么(i, j)就构成一个逆序对。
注意:逆序对统计的是"前面比后面大"的情况,这与常规的排序方向相反,这也是为什么它能反映序列的无序程度。
以数组 [3,1,2] 为例:
- (3,1) 是一个逆序对
- (3,2) 是另一个逆序对
- (1,2) 不是逆序对
所以这个数组总共有2个逆序对。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 暴力解法与优化思路
2.1 暴力解法分析
最直观的解法是双重循环:
cpp复制int count = 0;
for(int i = 0; i < n; i++) {
for(int j = i+1; j < n; j++) {
if(nums[i] > nums[j]) count++;
}
}
这种方法时间复杂度是O(n²),对于大规模数据(如n=10⁵)时,计算量会达到10¹⁰次,完全不可行。
2.2 分治思想引入
归并排序天然适合解决这个问题,因为:
- 分治策略将问题分解为子问题
- 合并过程可以利用已排序子数组的性质
- 时间复杂度可以优化到O(nlogn)
关键突破点在于:在合并两个有序子数组时,可以高效统计跨越这两个子数组的逆序对。
3. 归并排序解法详解
3.1 算法框架搭建
首先建立基本的归并排序框架:
cpp复制class Solution {
vector<int> tmp;
int ret = 0;
public:
int reversePairs(vector<int>& nums) {
int n = nums.size();
tmp.resize(n);
mergeSort(nums, 0, n-1);
return ret;
}
void mergeSort(vector<int>& nums, int left, int right) {
