算法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++]; // 将右元素放入临时数组
        }
    }
相关推荐
烽学长1 小时前
(附源码)基于Springboot+vue的图书阅读分享系统的设计与实现
java·spring boot·后端
Ivanqhz1 小时前
数据搬运是性能关键
java·服务器·网络·人工智能·深度学习
青山木1 小时前
RocketMQ 入门到原理(三):消息存储原理
java·后端·中间件·架构·rocketmq
MayBaymax1 小时前
Spring AI Alibaba Graph 实战:客服工单智能处理
java·ai·ai编程
阳明山水2 小时前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构
光依旧2 小时前
MCP实战手记系列(五):让工具返回一个能点的界面(文末附github源码链接)
java·spring ai·前端集成·mcp·mcp apps
APIshop2 小时前
淘宝选品接口实战:从召回、详情、佣金到转链的 Java 接入笔记
java
泡茶喝茶写代码2 小时前
量化数据进阶:多维实战篇(第 11 篇):历史涨跌停价:涨跌停序列与止损线测算
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据api
景熙55232 小时前
单体项目编写思路和落地形式
java·开发语言