当前位置: 首页 > news >正文

【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博客icon-default.png?t=N7T8https://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、题目介绍 首先阅读题目可以得出要点&#xff0c;即当前数大于后数时则当作一个【逆序对】&#xff0c;而题目是要求在一个数组中计算一共存…...

python经典百题之一个素数能被几个9整除

题目:判断一个素数能被几个9整除。 首先&#xff0c;我们需要明确素数的定义&#xff1a;素数是大于1&#xff0c;且只能被1和自身整除的整数。 下面将分别介绍三种实现方法&#xff0c;每种方法附上解题思路、实现代码、以及优缺点。最后&#xff0c;将对这三种方法进行总结…...

Thymeleaf 内联语法使用教程

1 表达式内联 Thymeleaf标准方言允许使用标签属性(th:)来实现很多的功能&#xff0c;但在有些场景之下&#xff0c;需要将表达式直接写入HTML 代码中和CSS代码中及JavaScript代码中【代码和html文件在一起&#xff0c;分能不开&#xff0c;待验证&#xff0c;有验证的朋友可…...

Django学习笔记-实现聊天系统

笔记内容转载自 AcWing 的 Django 框架课讲义&#xff0c;课程链接&#xff1a;AcWing Django 框架课。 CONTENTS 1. 实现聊天系统前端界面2. 实现后端同步函数 1. 实现聊天系统前端界面 聊天系统整体可以分为两部分&#xff1a;输入框与历史记录。 我们需要先修改一下之前代…...

C++转换函数

什么是转换函数? C转换函数是一种特殊的成员函数&#xff0c;用于将一个类的对象转换为另一个类型。它是通过在类中定义特定的函数来实现的。 转换函数的用途&#xff1a; 类型转换&#xff1a;转换函数可以将一个类的对象从一种类型转换为另一种类型。这样可以方便地在不同…...

Spring Boot中的@Controller使用教程

一 Controller使用方法&#xff0c;如下所示&#xff1a; Controller是SpringBoot里最基本的组件&#xff0c;他的作用是把用户提交来的请求通过对URL的匹配&#xff0c;分配个不同的接收器&#xff0c;再进行处理&#xff0c;然后向用户返回结果。下面通过本文给大家介绍Spr…...

【17】c++设计模式——>原型模式

原型模式的定义 c中的原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;其目的是通过复制&#xff08;克隆&#xff09;已有对象来创建新的对象&#xff0c;而不需要显示的使用构造函数创建对象&#xff0c;原型模式适用于创建复杂对象时&a…...

金三银四好像消失了,IT行业何时复苏!

文章目录 1. 宏观经济形势2. 技术发展趋势3. 教育与培训4. 远程工作和自由职业5. 行业需求和公司招聘计划结论 &#x1f389;欢迎来到Java面试技巧专栏~金三银四好像消失了&#xff0c;IT行业何时复苏&#xff01; ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…...

PDF文件超出上传大小?三分钟学会PDF压缩

PDF作为一种流行的文档格式&#xff0c;被广泛用于各种场合&#xff0c;然而有时候PDF文件的大小超出了上传限制&#xff0c;这时候我们就需要采取一些措施来减小PDF文件的大小&#xff0c;下面就给大家分享几个方法&#xff0c;一起来学习下吧~ 方法一&#xff1a;嗨格式压缩大…...

java入坑之国际化编程

一、字符编码 1.1概述 字符编码 --字符&#xff1a;0&#xff0c;a,我&#xff0c;①&#xff0c;,… --计算机只用0和1,1bit(0或者1) --ASCIL码(American Standard Code for Information Interchange) 美国信息交换标准代码&#xff0c;奠定计算机编码基础用一个字节(1Byte8b…...

Kafka客户端核心参数详解

这一部分主要是从客户端使用的角度来理解 Kakfa 的重要机制。重点依然是要建立自己脑海中的 Kafka 消费模型。Kafka 的 HighLevel API 使用是非常简单的&#xff0c;所以梳理模型时也要尽量简单化&#xff0c;主线清晰&#xff0c;细节慢慢扩展。 一、从基础的客户端说起 Kaf…...

踩大坑ssh免密登录详细讲解

目 录 问题背景 环境说明 免密登录流程说明 1.首先要在对应的用户主机名的情况下生成密钥对&#xff0c;在A服务器执行 2.将A服务器d公钥拷贝到B服务器对应的位置 3.在A服务器访问B服务器 免密登录流程 0.用户说明 1.目前现状演示 2.删除B服务器.ssh 文件夹下面的…...

操作系统八股

1、请你介绍一下死锁&#xff0c;产生的必要条件&#xff0c;产生的原因&#xff0c;怎么预防死锁 1、死锁 两个或两个以上的进程在执行过程中&#xff0c;因争夺共享资源而造成的一种互相等待的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系统处…...

Hudi SQL DDL

本文介绍Hudi在 Spark 和 Flink 中使用SQL创建和更改表的支持。 1.Spark SQL 创建hudi表 1.1 创建非分区表 使用标准CREATE TABLE语法创建表&#xff0c;该语法支持分区和传递表属性。 CREATE TABLE [IF NOT EXISTS] [db_name.]table_name[(col_name data_type [COMMENT col_co…...

gin 框架的 JSON Render

gin 框架的 JSON Render gin 框架默认提供了很多的渲染器&#xff0c;开箱即用&#xff0c;非常方便&#xff0c;特别是开发 Restful 接口。不过它提供了好多种不同的 JSON Render&#xff0c;那么它们的区别是什么呢&#xff1f; // JSON contains the given interface obje…...

《Dataset Condensation with Differentiable Siamese Augmentation》

《Dataset Condensation with Differentiable Siamese Augmentation》 在本文中&#xff0c;我们专注于将大型训练集压缩成显著较小的合成集&#xff0c;这些合成集可以用于从头开始训练深度神经网络&#xff0c;性能下降最小。受最近的训练集合成方法的启发&#xff0c;我们提…...

多普勒频率相关内容介绍

图1 多普勒效应 1、径向速度 径向速度是作用于雷达或远离雷达的速度的一部分。 图2 不同的速度 2、喷气发动机调制 JEM是涡轮机的压缩机叶片的旋转的多普勒频率。 3、多普勒困境 最大无模糊范围需要尽可能低的PRF&#xff1b; 最大无模糊速度需要尽可能高的PRF&#xff1b…...

win10睡眠快捷方式

新建快捷方式 如下图 内容如下 rundll32.exe powrprof.dll,SetSuspendState 0,1,0 下一步 点击完成即可。 特此记录 anlog 2023年10月6日...

C++中的static和extern关键字

1 声明和定义 声明就是告诉编译器有这个东西的存在&#xff0c;而定义则是这个东西的实现。 对于变量来说&#xff0c;声明就是告诉编译器存在这个名称的变量&#xff0c;定义则是给这个变量分配内存并赋值&#xff1a; // 变量声明&#xff0c;声明时不能赋值&#xff0c;如…...

JAVA经典百题之找完数

题目&#xff1a;一个数如果恰好等于它的因子之和&#xff0c;这个数就称为"完数"。例如61&#xff0b;2&#xff0b;3.编程找出1000以内的所有完数。 程序分析 首先&#xff0c;我们需要编写一个程序来找出1000以内的所有完数。"完数"是指一个数等于它的…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...