算法50,分治归并,数组中的逆序对

💡 算法核心思路

逆序对(前一天股价高于后一天)的产生分为三种情况:

  1. 两个元素都在左半部分(递归求解)。
  2. 两个元素都在右半部分(递归求解)。
  3. 一个在左半部分,一个在右半部分(合并时统计)。

归并排序的"合并两个阶段"恰好是左右子数组都有序的状态,此时可以高效地统计跨区间的逆序对。

💻 代码逐段解析

1. 初始化与入口

复制代码
int[] tmp; // 全局辅助数组,避免递归中频繁创建数组开辟内存
public int reversePairs(int[] nums) {
    int n=nums.length;
    tmp=new int[n];
    return mergeSort(nums,0,n-1);
}

2. 递归分治(拆分)

复制代码
public int mergeSort(int[] nums,int left,int right){
    if(left>right)return 0; // 递归终止条件(子数组长度为1或0)
    int ret=0;
    int mid=(left+right)/2; // 取中间点划分
    ret+=mergeSort(nums,left,mid); // 统计左子数组内部的逆序对
    ret+=mergeSort(nums,mid+1,right); // 统计右子数组内部的逆序对

3. 合并与统计逆序对(核心重点)

复制代码
int cur1=left,cur2=mid+1,i=0;
    while(cur1<=mid&&cur2<=right){
        if(nums[cur1]<=nums[cur2]){
            tmp[i++]=nums[cur1++]; // 左元素小,不构成逆序对,直接放入临时数组
        }else{
            ret+=mid-cur1+1; // ⭐核心公式:左子数组中 cur1 及右侧所有元素都大于当前右元素,直接统计数量
            tmp[i++]=nums[cur2++]; // 将右元素放入临时数组
        }
    }
相关推荐
代码什么用5 小时前
Spring基础使用
java·后端·spring
信奥卷王5 小时前
[GESP202609 六级] 分树规划
算法
Su米苏5 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
夏幻灵5 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
码云数智-园园5 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁5 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网6 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西6 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨6 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言