算法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++]; // 将右元素放入临时数组
        }
    }
相关推荐
Ivanqhz18 分钟前
MoE + LLM 应用
数据库·人工智能·pytorch·python·深度学习·算法·1024程序员节
西瓜拿铁好喝30 分钟前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
学长毕设32 分钟前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
lpfasd12334 分钟前
推荐算法进化史
算法·机器学习·推荐算法
明天也要努力学习38 分钟前
深入理解 JVM 垃圾回收(GC)
java·jvm
Pniubi1 小时前
力扣543二叉树的直径(深度优先搜索法(递归))
算法·leetcode·职场和发展
golang学习记1 小时前
IDEA 断点调试技巧:拖拽
java·ide·intellij-idea
Sayai1 小时前
Flink 日志解析任务性能优化实战:正则/Grok 预编译、Guava 缓存权重陷阱与 ES 写入隔离
java·大数据·性能优化·flink·实时计算
计算机毕设定制辅导-无忧学长1 小时前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法
Best_Liu~1 小时前
SpringBoot全局日期格式化
java·spring boot·后端