剑指 Offer 51. 数组中的逆序对

news2025/1/21 0:52:21

剑指 Offer 51. 数组中的逆序对

难度: h a r d \color{red}{hard} hard


题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1:

输入: [7,5,6,4]
输出: 5

限制:

0 < = 数组长度 < = 50000 0 <= 数组长度 <= 50000 0<=数组长度<=50000


算法

(归并排序)

首先先看一张图:
逆序对的数量.png

1. 逆序对的定义:

对于数列的第 i 个和第 j 个元素,如果满足 i < ja[i] > a[j],则其为一个逆序对。
重要的地方在于,一个元素可以不只是在一个逆序对中存在。如果 k > j > ia[i] > a[j] > a[k],那么这里
有两个含 a[i] 的逆序对,分别是 (a[i], a[j])(a[i], a[k]), a[i]是可以使用多次的。
(太长不看)
举个栗子:

num:  2 3 4 5 6 1
id :  0 1 2 3 4 5

一句话概括就是求当前数组中存在几个比当前位置大的,(或者后面有几个数字比他小的) 加上2在第一个位置,后面比它小的数字是1,所以2的逆序对是(2, 1), 同理(3, 1) (4, 1) (5, 1) (6, 1)
答案是5。

2. 分析问题:

采用分治法来求解问题,为什么不是树状数组呢~~(buhui)~~,因为分治法求解此题比较简单。
按照y总的说法:我们将序列从中间分开,将逆序对分成三类:

  1. 两个元素都在左边;
  2. 两个元素都在右边;
  3. 两个元素一个在左一个在右;

算法的大致框架为:

  1. 递归算 左边 \color{red}{左边} 左边的;
  2. 递归算 右边 \color{red}{右边} 右边的;
  3. 一个左一个右 \color{red}{一个左一个右} 一个左一个右的;
  4. 把三个结果加在一起
    10048_7f952550db-逆序对.png

3. 问题详解:

  1. 在一些题解中说到可以不用计算前两种情况,只需要看第三种情况,我的理解是:需要真正知道归并排序在做什么。这就是我们上面的那张图,归并排序分为两个大步骤; 分 \color{red}{分} 治 \color{red}{治} ,从上面的栗子中我们看出,分的步骤会把所有的数组分为一个单独的数字,所以也就解释了为什么不需要考虑前两种情况,最种都会到第三中情况上,因为只有每组只有一个数字,它没有人同组,1就是1,怎么变成2,我就吃了一碗粉,为什么付两碗的钱。所以最终都是会变成第三种情况。
  2. 下面解释治.
    逆序对详解.png
  3. 第一步对元素进行排序,可以看到直接是求两个单独元素的逆序对,如果是逆序对,答案ans++,然后合并两个数字变成一个有序的数组,
  4. 第二步,在对两个分组的数字进行求逆序对,此时没有到只剩下两个分组的情况,可以把这些步骤看作是内部之间求逆序对。
  5. 第三步就是两个分组求逆序对。可以看到此时前后两个分组都是有序的,前面的数组的下边为l..mid,后面的下标为mid + 1...r,我们可以在归并的时候是需要把两个数组的值重新赋值到原数组中的,所以就可以比较两个数组的值,也就是可以求逆序对。如果A数组的值q[i] 大于B数组的值q[j],代表在A数组中i~mid都是大于q[j]的,所以对于q[j]来说他的逆序对数量为mid - i + 1,同理,其他的逆序对也可以这么求。

复杂度分析

  • 时间复杂度 O ( n l o g n ) O(n logn) O(nlogn),其中 n n n 是链表的长度。需要遍历链表一次

  • 空间复杂度 : O ( n ) O(n) O(n),因为归并排序需要用到一个临时数组。

C++ 代码

class Solution {
public:
    int reversePairs(vector<int>& nums) {
        return merge_sort(nums, 0, nums.size() - 1);
    }

    int merge_sort(vector<int>& nums, int l, int r)
    {
        if (l >= r) return 0;
        int mid = (l + r) / 2;
        // 分
        int res = merge_sort(nums, l, mid) + merge_sort(nums, mid + 1, r);
        // 并
        int i = l, j = mid + 1, k = 0;
        vector<int> temp;
        while (i <= mid && j <= r)
        {
            if (nums[i] <= nums[j]) temp.push_back(nums[i ++]);
            else
            {
                res += mid - i + 1;
                temp.push_back(nums[j ++]);
            }
        }

        while (i <= mid) temp.push_back(nums[i ++]);
        while (j <= r) temp.push_back(nums[j ++]);

        i = l;
        for (auto x : temp) nums[i ++] = x;

        return res;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/414451.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么设计秒杀系统?

秒杀系统需要考虑哪些要素&#xff1f; 要能支持高并发用户体验要好&#xff0c;不要返回异常信息对系统要友好&#xff08;针对秒杀可以做业务上的隔离&#xff0c;单独把秒杀系统部署到独立的集群服务器上&#xff1b;可动态配置业务参数&#xff0c;比如商品金额&#xff0…

电磁兼容(EMC)的标准与测试内容

在国际范围上&#xff0c;电磁兼容标准的制定已经有了70多年的发展历程&#xff0c;最早为了保护无线电通信和广播&#xff0c;国际无线电干扰特别委员会&#xff08;CISPR&#xff09;对各种用电设备和系统提出了相关的电磁干扰发射限值和测量方法。到了20世纪60&#xff5e;7…

机器学习:基于朴素贝叶斯(Naive Bayes)的分类预测

目录 一、简介和环境准备 简介&#xff1a; 环境&#xff1a; 二、实战演练 2.1使用葡萄&#xff08;Wine&#xff09;数据集&#xff0c;进行贝叶斯分类 1.数据导入 2.模型训练 3.模型预测 2.2模拟离散数据集–贝叶斯分类 1.数据导入、分析 2.模型训练、预测 三、原…

TiDB进阶篇-TiDB Server架构

简介 较深入的介绍TiDB Server。 TiDB Server 架构 图解 1.下面是负责SQL语句的解析和优化。 2.下面试负责TiKV存储多版本&#xff0c;过期版本的清理作用。 3.复杂SQL的拆分&#xff08;如果是点查那么就不需要经过DistSQL&#xff09;。 4.事务相关。 5.负责PD和TiKV的通信…

js 事件流程

描述 JavaScript 的执行是单线程的&#xff0c;后面的任务需要等待前面的任务完全完成后&#xff0c;再去执行。DOM 事件&#xff08;文件的加载等&#xff09;、定时器、网络请求等事件&#xff0c;并不会消耗 CPU&#xff0c;这些事件无需等候&#xff0c;所以出现了异步。主…

Java后端新人入职第一天,环境搭建,全看这篇就行了

本文主要是记录一下一个新人java后端开发来到一个新公司,如何快速将自己的相关开发环境搭建好,包括Java、Maven、Tomcat、idea、Redis、Mysql等等,有的公司会有相关版本的要求,不过安装配置步骤基本一样的,我这里就以目前比较流行的版本进行详细说明。 一:基础环境搭建:…

Arduino开发之如何连接GPS模块?

文章目录0、引言1、GPS模块说明2、接调试助手测试GPS模块接收数据3、代码编写4、功能演示0、引言 NEO-6M/7M GPS模块&#xff0c;具有高灵敏度、低功耗、小型化、高追踪灵敏度&#xff0c;大大扩大了其定位的覆盖面&#xff0c;在普通GPS接收模块不能定位的地方&#xff0c;如狭…

编译原理考试大题分析【太原理工大学】

有些基本公式可以看这里&#xff0c;大题内容请以本篇为准&#xff01;https://blog.csdn.net/m0_52861684/article/details/130071191?spm1001.2014.3001.5501 之前说错了&#xff0c;考试题型没有简答题和填空题&#xff0c;只有十个选择题是 20 分&#xff0c;其余全是大题…

ESP32设备驱动-VEML6075紫外线(UV)光传感器驱动

VEML6075紫外线(UV)光传感器驱动 文章目录 VEML6075紫外线(UV)光传感器驱动1、VEML6075介绍2、硬件准备3、软件准备4、驱动实现1、VEML6075介绍 VEML6075 可感应 UVA 和 UVB 光,并使用 CMOS 工艺将光电二极管、放大器和模拟/数字电路集成到单个芯片中。 应用 UV 传感器时,它…

ChatGPT和GPT-4带你选笔记本电脑

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

最近ChatGPT封号太严重了,这里是解封攻略步骤(建议收藏)

这个周末&#xff0c;先是意大利暂时封杀ChatGPT&#xff0c;限制OpenAI处理本国用户信息。 接着&#xff0c;据韩国媒体报道&#xff0c;三星导入ChatGPT不到20天&#xff0c;便曝出机密资料外泄。 还没结束&#xff0c;又有大量网友发现ChatGPT目前停止注册&#xff0c;开始…

【vue】vue中下载文件的方法

文章目录1. 下载后端返回文件1.1 后端为post请求返回二进制流文件URL.createObjectURLFileReader1.2 后端直接返回get请求文件2. 下载本地文件1. 下载后端返回文件 1.1 后端为post请求返回二进制流文件 Blob Blob对象标识一个不可变、原始数据的类文件对象。Blob表示的不一定…

RabbitMQ( 发布订阅模式 ==> FanoutExchange )

本章目录&#xff1a; 何为发布订阅模式FanoutExchange具体使用一、何为发布订阅模式 在上一篇文章中&#xff0c;我们创建了Work Queue并且发送任务&#xff0c;在Work Queue中&#xff0c;每个任务只会被一个消费者消费&#xff0c;任务消费后就被清除了。 而在本篇中&…

0202心跳和服务续约源码解析-nacos2.x-微服务架构

文章目录1 客户端心跳任务2 服务端处理2.1 服务注册时开启客户端心跳检查2.2 客户端发送心跳任务续约2.3 服务实例移除2.4 心跳任务闭环结语1 客户端心跳任务 在上一篇文章0201服务注册源码解析-nacos2.x-微服务架构分析客户端服务注册的时候&#xff0c;流程在NacosNamingSer…

重装系统下载网址

[置顶]无论会不会安装系统&#xff0c;都一定会需要&#xff0c;觉得内容不错欢迎一键三连哦 稳定 | 方便 | 好用 1、MSDN 用过最简单好用&#xff0c;下载不限速&#xff0c;支持迅雷、IDM多种下载方式 https://www.xitongku.com 2、Windows系统下载仓储站 为小白重装系统提供…

KIOPTRIX: LEVEL 4通关详解

环境配置 vulnhub上下载的文件没有vmx 去3的文件里偷一个 记事本打开把所有Kioptrix3_vmware改成Kioptrix4_vmware 然后网卡地址随便改一下 打开后会提示找不到虚拟机,手动选一下就行了 信息收集 漏洞发现 web一上去就是一个登录框 扫路径发现database.sql 但是密码是错的…

高通开发系列 - linux arm64 toolchain交叉编译器编译错误

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 概述下载aarch64交叉编译器编译使能编译环境使能defconfig编译问题1:address-of-packed-member问题2:attribute-alias=问题3:array…

Kubernetes 笔记(14)— 滚动更新、定义应用版本、实现应用更新、管理应用更新、添加更新描述

滚动更新&#xff0c;使用 kubectl rollout 实现用户无感知的应用升级和降级。 1. 定义应用版本 在 Kubernetes 里&#xff0c;版本更新使用的不是 API 对象&#xff0c;而是两个命令&#xff1a;kubectl apply 和 kubectl rollout&#xff0c;当然它们也要搭配部署应用所需要…

人工智能作业之遗传算法

遗传算法1.遗传算法定义2.相关术语3.遗传算法的主要步骤4.遗传算法的参数设计原则5.代码实现1.遗传算法定义 遗传算法&#xff08;Genetic Algorithm, GA&#xff09;起源于对生物系统所进行的计算机模拟研究。它是模仿自然界生物进化机制发展起来的随机全局搜索和优化方法&am…

java 婚恋交友网站Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 婚恋交友网站是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…