【LeetCode力扣】LCR170 使用归并排序的思想解决逆序对问题(详细图解)

目录
1、题目介绍
2、解题思路
2.1、暴力破解法
2.2、归并排序思想
2.2.1、画图详细讲解
2.2.2、归并排序解决逆序对的代码实现

1、题目介绍
首先阅读题目可以得出要点,即当前数大于后数时则当作一个【逆序对】,而题目是要求在一个数组中计算一共存在多少个这样的逆序对并输出结果。
原题链接:LCR 170. 交易逆序对的总数 - 力扣(LeetCode)
2、解题思路
2.1、暴力破解法
看到这里的第一反应就是这不是很简单吗?心想着这困难题也不过如此吧(笑)。
就是直接使用暴力破解法,只需要两个for循环嵌套,一个record[ i ]在原地,另一个record[ j ]将后面所有遍历一遍,只要比record[ i ]的小就将计算器count加1,然后i++再从头遍历,知道找完所有,最后返回计数器count即可,于是便奋笔疾书写了起来。
int reversePairs(int* record, int recordSize) {if (recordSize == 0){return 0;}int count = 0;int i = 0, j = 0;for (i = 0; i < recordSize - 1; i++){for (j = i + 1; j < recordSize; j++){if (record[i] > record[j]){count++;}}}return count;
}
当写完然后测试了简答数据无误,然后自信满满地点击提交,结果却直接被打脸。
看了报错结果才恍然大悟,看题目时漏看了数组长度。
题目设置的数组长度最长可达 50000,因此使用暴力破解法虽然非常简单,但是时间复杂度也非常大为O(n^2),这肯定会超出时间限制的。因此需要使用一种时间复杂度较小的遍历。到了这里才终于理解了这道题为什么是困难题!!!
2.2、归并排序思想
这里思考了一下,只要能找到 一种时间复杂度低,并且通过比较排序的算法,在比较排序的过程中顺便进行记录,这样的化就能够解决这个问题了。
于是归并排序便浮现在眼前,归并排序的时间复杂度很低只有O(nlogn),并且也是通过比较的方式进行排序,那么只需要在传统的归并排序算法中添加一些用于记录前者大于后者计算器即可。
简单回顾一下归并排序的知识:
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用递归或者说是分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序,它包含这样三个步骤:
- 分解:把长度为n的待排序序列分成两个长度为n/2的子序列。例如L代表头部,M代表中点,R代表尾部,将[ L,R ]分成[ L,M ]和[ M+1,R ]。
- 解决:使用归并排序递归地排序两个子序列。
- 合并:将两个排序好的子序列[ L,M ]和[ M+1,R ]合并成一个最终的排序序列。
在待排序序列长度为 1 的时候,递归开始「回升」,因为我们默认长度为 1 的序列是排好序的。简单来说就是:当分到单个子序列只剩下一个数字时,一个数字就是天然了有序,即此时左侧和右侧都排好序了,然后递归进行回升操作。
由于篇幅原因,如果想要更加详细地了解有关归并排序的知识,可以前往往期博客中阅读:
【算法与数据结构】归并排序的代码实现(详细图解)以及master公式的讲解_Hacynn的博客-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/133516177?spm=1001.2014.3001.5501
2.2.1、画图详细讲解
假设我们通过归并排序的「回升」操作已经得到了两个已排序的子序列并等待合并,这两个子序列假设为:左子序列[ 8,15,17,22,35 ]和右子序列[ 9,12,15,30,38 ]。然后用malloc开辟辅助数组help,并定义一个变量sum用于记录当前逆序对的个数。
一开始我们先用p1指向左子序列的头部,p2指向右子序列的头部,i指向help数组的头部。

此时开始比较p1和p2指向的值,我们发现p1小于p2,不符合逆序对的前者大于后者,因此不做其他操作,直接将值放入help数组 i 位置中,并且分别进行p1++和i++,使指向下一个元素。

重复p1和p2的比较操作,发现此时p1大于p2,此时记录逆序对的sum本应该自增1。
但是这里我们可以发现一个规律:因为左子序列是有序的,如果p1此时的数比p2大,那就证明p1后面的数字也依然比p2大,因此逆序对应该有M-p1+1即4个,分别是:(15,9)、(17,9)、(22,9)、(35,9)。
所以此时sum应该+4,并将p2所指的较小值存入help中。

i++、p2++;
此时p1仍然大于p2,再次使用M-p1+1计算出逆序对为4个,分别是(15,12)、(17,12)、(22,12)、(35,12)。
此时 sum = sum+4,并将12存入help中。

i++,p2++;
注意特殊:此时p1 == p2,该算法在等于时尤为关键,当相等时应该将左侧p1的15放入help中并p1++,如果放的是右侧p2的15存入,就会丢失一部分逆序对,这个原理读者可以自己画图理解。

剩下的部分依然按照此规律进行操作,最终算出该轮遍历的逆序对数sum。
2.2.2、归并排序解决逆序对的代码实现
int ExternalSort(int* arr, int L, int M, int R)
{int* help = (int*)malloc(sizeof(int) * (R - L + 1));int p1 = L;int p2 = M + 1;int sum = 0;int i = 0;while ((p1 <= M) && (p2 <= R)){//p1 大于 p2 则计算出逆袭对个数并加入sum中,p1小于p2时则给0(即不操作)sum += arr[p1] > arr[p2] ? (M - p1 + 1) : 0;//较小的数拷贝进help数组,相等时拷贝p1指针的数help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];}//当有一个子序列遍历完了,则将另外一个子序列中剩余的数据全部放入help数组中while (p1 <= M) { help[i++] = arr[p1++]; }while (p2 <= R) { help[i++] = arr[p2++]; }//将辅助数组help中已经合并完成的数据传回给原数组arr的相应位置for (i = 0; i < (R - L + 1); i++){arr[L + i] = help[i];}free(help);help = NULL;return sum; //返回本轮操作的sum值}int MergeSort(int* arr, int L, int R)
{if (L == R){return 0;}int mid = L + (R - L) / 2;return MergeSort(arr, L, mid) + //对拆分的左子序列进行递归操作MergeSort(arr, mid + 1, R) + //对拆分的右子序列进行递归操作ExternalSort(arr, L, mid, R); //外部排序并计算出逆序对sum
}int reversePairs(int* record, int recordSize) {int ret = 0;if (recordSize == 0) //对空数组进行判断{return 0;}ret = MergeSort(record, 0, recordSize - 1);return ret;
}
到这里,关于本题的解题过程就结束了 。

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
相关文章:
【LeetCode力扣】LCR170 使用归并排序的思想解决逆序对问题(详细图解)
目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、归并排序思想 2.2.1、画图详细讲解 2.2.2、归并排序解决逆序对的代码实现 1、题目介绍 首先阅读题目可以得出要点,即当前数大于后数时则当作一个【逆序对】,而题目是要求在一个数组中计算一共存…...
python经典百题之一个素数能被几个9整除
题目:判断一个素数能被几个9整除。 首先,我们需要明确素数的定义:素数是大于1,且只能被1和自身整除的整数。 下面将分别介绍三种实现方法,每种方法附上解题思路、实现代码、以及优缺点。最后,将对这三种方法进行总结…...
Thymeleaf 内联语法使用教程
1 表达式内联 Thymeleaf标准方言允许使用标签属性(th:)来实现很多的功能,但在有些场景之下,需要将表达式直接写入HTML 代码中和CSS代码中及JavaScript代码中【代码和html文件在一起,分能不开,待验证,有验证的朋友可…...
Django学习笔记-实现聊天系统
笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 CONTENTS 1. 实现聊天系统前端界面2. 实现后端同步函数 1. 实现聊天系统前端界面 聊天系统整体可以分为两部分:输入框与历史记录。 我们需要先修改一下之前代…...
C++转换函数
什么是转换函数? C转换函数是一种特殊的成员函数,用于将一个类的对象转换为另一个类型。它是通过在类中定义特定的函数来实现的。 转换函数的用途: 类型转换:转换函数可以将一个类的对象从一种类型转换为另一种类型。这样可以方便地在不同…...
Spring Boot中的@Controller使用教程
一 Controller使用方法,如下所示: Controller是SpringBoot里最基本的组件,他的作用是把用户提交来的请求通过对URL的匹配,分配个不同的接收器,再进行处理,然后向用户返回结果。下面通过本文给大家介绍Spr…...
【17】c++设计模式——>原型模式
原型模式的定义 c中的原型模式(Prototype Pattern)是一种创建型设计模式,其目的是通过复制(克隆)已有对象来创建新的对象,而不需要显示的使用构造函数创建对象,原型模式适用于创建复杂对象时&a…...
金三银四好像消失了,IT行业何时复苏!
文章目录 1. 宏观经济形势2. 技术发展趋势3. 教育与培训4. 远程工作和自由职业5. 行业需求和公司招聘计划结论 🎉欢迎来到Java面试技巧专栏~金三银四好像消失了,IT行业何时复苏! ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&…...
PDF文件超出上传大小?三分钟学会PDF压缩
PDF作为一种流行的文档格式,被广泛用于各种场合,然而有时候PDF文件的大小超出了上传限制,这时候我们就需要采取一些措施来减小PDF文件的大小,下面就给大家分享几个方法,一起来学习下吧~ 方法一:嗨格式压缩大…...
java入坑之国际化编程
一、字符编码 1.1概述 字符编码 --字符:0,a,我,①,,… --计算机只用0和1,1bit(0或者1) --ASCIL码(American Standard Code for Information Interchange) 美国信息交换标准代码,奠定计算机编码基础用一个字节(1Byte8b…...
Kafka客户端核心参数详解
这一部分主要是从客户端使用的角度来理解 Kakfa 的重要机制。重点依然是要建立自己脑海中的 Kafka 消费模型。Kafka 的 HighLevel API 使用是非常简单的,所以梳理模型时也要尽量简单化,主线清晰,细节慢慢扩展。 一、从基础的客户端说起 Kaf…...
踩大坑ssh免密登录详细讲解
目 录 问题背景 环境说明 免密登录流程说明 1.首先要在对应的用户主机名的情况下生成密钥对,在A服务器执行 2.将A服务器d公钥拷贝到B服务器对应的位置 3.在A服务器访问B服务器 免密登录流程 0.用户说明 1.目前现状演示 2.删除B服务器.ssh 文件夹下面的…...
操作系统八股
1、请你介绍一下死锁,产生的必要条件,产生的原因,怎么预防死锁 1、死锁 两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处…...
Hudi SQL DDL
本文介绍Hudi在 Spark 和 Flink 中使用SQL创建和更改表的支持。 1.Spark SQL 创建hudi表 1.1 创建非分区表 使用标准CREATE TABLE语法创建表,该语法支持分区和传递表属性。 CREATE TABLE [IF NOT EXISTS] [db_name.]table_name[(col_name data_type [COMMENT col_co…...
gin 框架的 JSON Render
gin 框架的 JSON Render gin 框架默认提供了很多的渲染器,开箱即用,非常方便,特别是开发 Restful 接口。不过它提供了好多种不同的 JSON Render,那么它们的区别是什么呢? // JSON contains the given interface obje…...
《Dataset Condensation with Differentiable Siamese Augmentation》
《Dataset Condensation with Differentiable Siamese Augmentation》 在本文中,我们专注于将大型训练集压缩成显著较小的合成集,这些合成集可以用于从头开始训练深度神经网络,性能下降最小。受最近的训练集合成方法的启发,我们提…...
多普勒频率相关内容介绍
图1 多普勒效应 1、径向速度 径向速度是作用于雷达或远离雷达的速度的一部分。 图2 不同的速度 2、喷气发动机调制 JEM是涡轮机的压缩机叶片的旋转的多普勒频率。 3、多普勒困境 最大无模糊范围需要尽可能低的PRF; 最大无模糊速度需要尽可能高的PRF;…...
win10睡眠快捷方式
新建快捷方式 如下图 内容如下 rundll32.exe powrprof.dll,SetSuspendState 0,1,0 下一步 点击完成即可。 特此记录 anlog 2023年10月6日...
C++中的static和extern关键字
1 声明和定义 声明就是告诉编译器有这个东西的存在,而定义则是这个东西的实现。 对于变量来说,声明就是告诉编译器存在这个名称的变量,定义则是给这个变量分配内存并赋值: // 变量声明,声明时不能赋值,如…...
JAVA经典百题之找完数
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如61+2+3.编程找出1000以内的所有完数。 程序分析 首先,我们需要编写一个程序来找出1000以内的所有完数。"完数"是指一个数等于它的…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
