leetcode LCR 170.交易逆序对的总数

一、问题描述

二、解题思路

整体思路

可以借鉴**归并排序(递归)**的求解过程。假设数组如图所示,总过程为:

(1)首先找到中间位置mid;

(2)在left,mid区间内统计逆序对的数量+排序;

(3)再在mid+1,right区间内统计逆序对的数量+排序;

(4)最后再一左一右统计逆序对的数量+排序;

(5)将三个数量累加,即为所求。

具体思路

(1)首先,考虑递归出口,如果left>=right,即区间内只有1个数或者没有数,此时逆序对的数量为0,return0;

(2)寻找中间位置,执行左区间寻找+排序、右区间寻找+排序,代码如下:

//1.寻找中间位置

int mid=left+(right-left)/2;

//2.左区间寻找+排序、右区间寻找+排序

ret+=mergeSort(nums,left,mid);

ret+=mergeSort(nums,mid+1,right);

(3)由于递归需要保证子问题一样,所以我们在一左一右统计逆序对的数量后,也进行排序处理。我们处理的总策略是寻找左边更大的数的个数,处理过程如下,此时的数组如图。当cur1<=mid且cur2<=right时进行归并处理,并进行逆序对数量统计:

<1>当numscur1<=numscur2时,执行tmpi++=numscur1++;

<2>当numscur1>numscur2时,此时cur1,mid区间内的数均比numscur2大,所以ret+=mid-cur1+1,tmpi++=numscur2++;

(4)循环结束后,将归并排序的过程完成:

//4.处理没有排序完的数字

while(cur1<=mid) tmpi++=numscur1++;

while(cur2<=right) tmpi++=numscur2++;

(5)排序完成后用排序完的辅助数组tmp覆盖原本的数组nums:

//5.还原nums数组

for(int i=left;i<=right;i++)

numsi=tmpi-left;

(6)最后返回ret;

三、代码实现

时间复杂度:T(n)=O(nlogn)

空间复杂度:S(n)=O(n)

cpp 复制代码
class Solution {
    vector<int> tmp;
public:
    int reversePairs(vector<int>& nums) {
       //结合归并排序
       tmp.resize(nums.size());
       return mergeSort(nums,0,nums.size()-1);
    }

    int mergeSort(vector<int>& nums,int left,int right){
        //递归出口
        if(left>=right) return 0;

        int ret=0;
        //1.寻找中间位置
        int mid=left+(right-left)/2;
        //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;
                tmp[i++]=nums[cur2++];
            }
        }
        //4.处理没有排序完的数字
        while(cur1<=mid) tmp[i++]=nums[cur1++];
        while(cur2<=right) tmp[i++]=nums[cur2++];
        //5.还原nums数组
        for(int i=left;i<=right;i++)
            nums[i]=tmp[i-left];
        //6.返回ret
        return ret;
    }
};
相关推荐
程序猿编码9 分钟前
不依赖 vLLM/llama.cpp:一套面向学习的 DeepSeek-R1 CUDA 推理实现
c++·学习·语言模型·llama·vllm·大模型推理
kiracrimson28 分钟前
string 容器:从 C 字符串到会自己扩容的类
开发语言·数据结构·c++·stl
程序猿编码32 分钟前
纯 C++ 手写 LLM 推理引擎:分页 KV 缓存、连续批、多卡张量并行全部内置
c++·深度学习·缓存·大模型推理·自动微分·模型推理
一条闲鱼_mytube38 分钟前
分布式 ID 生成方案:雪花算法与号段模式
分布式·算法·wpf
Msir_Modern44 分钟前
Noita 元胞沙盒笔记
算法·unity·c#·游戏引擎·元胞自动机
G018_star sky♬1 小时前
nodeJS他是如何用JavaScript封装C++的呢
开发语言·javascript·c++
choumin2 小时前
C++中std::move和std::forward的关系和区别
c++·std move·std forward·关系和区别
木井巳2 小时前
【动态规划: 路径问题】不同路径
java·算法·leetcode·动态规划
程序猿编码2 小时前
YOLOv5/v7/YOLOX 全支持:基于 TensorRT 的工业视觉推理底座详解
c++·yolo·机器学习·推理·模型推理
yuanxi2002 小时前
大众汽车集团或暂停印度电动汽车投资:PSS⁵谈判力视角
职场和发展·创业创新·学习方法