(排序) 剑指 Offer 51. 数组中的逆序对 ——【Leetcode每日一题】

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

难度:困难

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

示例 1:

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

限制

  • 0 <= 数组长度 <= 50000

💡思路:归并排序

预备知识

归并排序」是用分治思想,分治模式在每一层递归上有三个步骤:

  1. 分解(Divide):将 n 个元素分成个含 n/2 个元素的子序列。
  2. 解决(Conquer):用 合并排序法 对两个子序列递归的排序。
  3. 合并(Combine):合并两个已排序的子序列已得到排序结果。

在这里插入图片描述
具体的我们以一组无序数列{14,12,15,13,11,16}为例分解说明,如下图所示:

在这里插入图片描述

在待排序序列长度为 1 的时候,递归开始「回升」,因为我们默认长度为 1 的序列是排好序的。

具体思路

那么求逆序对和归并排序又有什么关系呢?关键就在于「归并」当中「」的过程。

合并阶段 本质上是 合并两个排序数组 的过程:

  • 每当遇到 左子数组当前元素 > 右子数组当前元素 时,意味着
    • 左子数组当前元素i 至 末尾元素m」 与 「右子数组当前元素」 构成了若干 「逆序对」 ;
    • 逆序对数 cnts += (m - i + 1)
  • 考虑在归并排序的合并阶段统计「逆序对」数量,完成归并排序时,也随之完成所有逆序对的统计。

🍁代码:(C++、Java)

C++

class Solution {
private:int cnts = 0;void mergeSort(vector<int>& nums, vector<int>& tmp, int l, int h){if(h - l < 1) return;//分解int m = l + (h - l) / 2;mergeSort(nums, tmp, l, m);mergeSort(nums, tmp, m + 1, h);//解决 + 合并int k = l, i = l, j = m + 1;while(i <= m || j <= h){if(i > m) tmp[k++] = nums[j++];else if(j > h || nums[i] <= nums[j]) tmp[k++] = nums[i++];else{//此时i~m对应数组中的数都比nums[j]大tmp[k++] = nums[j++];cnts += (m - i + 1);} }for(k = l; k <= h; k++){nums[k] = tmp[k];}}
public:int reversePairs(vector<int>& nums) {vector<int> tmp(nums.size());//辅助数组,临时记录中间合并的子数组mergeSort(nums, tmp, 0, nums.size() - 1);return cnts;}
};

Java

class Solution {private int cnts = 0;private void mergeSort(int[] nums, int[] tmp, int l, int h){if(h - l < 1) return;//分解int m = l + (h - l) / 2;mergeSort(nums, tmp, l, m);mergeSort(nums, tmp, m + 1, h);//解决 + 合并int k = l, i = l, j = m + 1;while(i <= m || j <= h){if(i > m) tmp[k++] = nums[j++];else if(j > h || nums[i] <= nums[j]) tmp[k++] = nums[i++];else{//此时i~m对应数组中的数都比nums[j]大tmp[k++] = nums[j++];cnts += (m - i + 1);} }for(k = l; k <= h; k++){nums[k] = tmp[k];}}public int reversePairs(int[] nums) {int[] tmp = new int[nums.length];//辅助数组,临时记录中间合并的子数组mergeSort(nums, tmp, 0, nums.length - 1);return cnts;}
}

🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:

  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),其中 n 为数组的长度,同归并排序 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( n ) O(n) O(n),归并排序需要用到一个临时数组。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker关于下载,镜像配置,容器启动,停止,查看等基础操作

系列文章目录 文章目录 系列文章目录前言一、安装Docker并配置镜像加速器二、下载系统镜像&#xff08;Ubuntu、 centos&#xff09;三、基于下载的镜像创建两个容器 &#xff08;容器名一个为自己名字全拼&#xff0c;一个为首名字字母&#xff09;四、容器的启动、 停止及重启…

STM32电源名词解释

STM32电源架构 常用名词 VCC Ccircuit 表示电路&#xff0c;即接入电路的电压。 VDD Ddevice 表示器件&#xff0c; 即器件内部的工作电压。 VSS Sseries 表示公共连接&#xff0c;通常指电路公共接地端电压。 VDDA Aanalog 表示模拟&#xff0c;是模拟电路部分的电源。主要为…

【C语言】C语言用数组算平均数,并输出大于平均数的数

题目 让用户输入一系列的正整数&#xff0c;最后输入“-1”表示输入结束&#xff0c;然后程序计算出这些数的平均数&#xff0c;最后输出输入数字的个数和平均数以及大于平均数的数 代码 #include<stdio.h> int main() {int x;double sum 0;int cnt 0;int number[100…

Linux服务——http协议及nginx服务

目录 一、HTTP协议 1、跨网络的主机间通讯方式 套接字相关的系统调用 2、HTTP协议访问网站的过程 3、http协议状态码分类 常见的http协议状态码 4、MIME 5、URL组成 6、HTTP协议版本 7、系统处理http请求的工作模式 8、apache与nginx的区别 二、I/O模型 I/O模型相关…

Docker常用操作命令(一)

Docker常用操作命令&#xff08;一&#xff09; 1、搜索镜像 docker search命令搜索存放在 Docker Hub中的镜像,此命令默认Docker会在Docker Hub中搜索镜像&#xff0c;可以配置了其他镜像仓库 [rootzch01 ~]# docker search centos NAME:镜像仓库名称DESCRIPTION:镜像仓库描…

测试框架pytest教程(5)运行失败用例-rerun failed tests

# content of test_50.py import pytestpytest.mark.parametrize("i", range(50)) def test_num(i):if i in (17, 25):pytest.fail("bad luck") 运行这个文件&#xff0c;2个失败&#xff0c;48个通过。 要运行上次失败的测试用例&#xff0c;可以使用--l…

中大许少辉博士中国建筑出版传媒八一新书《乡村振兴战略下传统村落文化旅游设计》百度百科新闻

中大许少辉博士中国建筑出版传媒八一新书《乡村振兴战略下传统村落文化旅游设计》百度百科新闻&#xff1a; 乡村振兴战略下传统村落文化旅游设计 - 百度百科 https://baike.baidu.com/item/乡村振兴战略下传统村落文化旅游设计/62588677 概览 《乡村振兴战略下传统村落文化旅游…

Python功能制作之简单的3D特效

需要导入的库&#xff1a; pygame: 这是一个游戏开发库&#xff0c;用于创建多媒体应用程序&#xff0c;提供了处理图形、声音和输入的功能。 from pygame.locals import *: 导入pygame库中的常量和函数&#xff0c;用于处理事件和输入。 OpenGL.GL: 这是OpenGL的Python绑定…

Java接口详解

接口 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本上的USB口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以插&#xff1a;U盘&#xff0c;鼠标&#xff0c;键盘等所有符合USB协议的设备 电源插座插孔上&#xff0c;…

构建智慧停车场:4G DTU实现无线数据高速传输

物联网技术的快速发展使得各种设备能够实现互联互通&#xff0c;无线网络技术给我们的日常生活带来了极大的便利。其中的网络技术如无线WiFi及4G网络已经成为了物联网应用中不可或缺的组成部分。而在工业领域中对4G无线路由器的应用是非常广泛的&#xff0c;人们通过4G工业路由…

为何汽车品牌如此钟爱数字人?揭秘一种很新的「交互」营销思路

随着新能源补贴退坡&#xff0c;互联网行业高速发展的红利衰退&#xff0c;汽车行业竞争越来越激烈。 在数智化潮流冲击下&#xff0c;传统车企和新势力汽车品牌都纷纷借助数字人营销&#xff0c;打破增长困境&#xff0c;致力于推动数字人在车端以及营销内容的广泛应用&#…

Server2016安装SQL server数据库遇到异常解决

首先看几个会出现的异常&#xff0c;下边看解决办法&#xff1a; 第一步: 先修改安装包x86\setup目录下的setupsql.exe,以Xp&#xff0c;SP3兼容模式运行&#xff0c; 这个右键&#xff0c;属性&#xff0c;兼容性&#xff0c;修改就行&#xff0c;类似这样 第二步: 修改c:…