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

算法的学习笔记—数组中的逆序对(牛客JZ51)

在这里插入图片描述

img

😀前言
在算法和数据结构领域,"逆序对"是一个经典问题。它在数组中两个数字之间定义,若前面的数字大于后面的数字,则这两个数字组成一个逆序对。我们要做的就是,给定一个数组,找出数组中所有的逆序对并计算其总数。

🏠个人主页:尘觉主页

文章目录

  • 🥰数组中的逆序对
    • 😄问题描述
      • 示例
    • 😃解题思路
      • 归并排序思想
      • 具体步骤
    • 💖代码实现
      • 代码讲解
      • 时间复杂度分析
    • 😄总结

🥰数组中的逆序对

NowCoder

😄问题描述

给定一个数组,数组中的两个数字如果满足以下条件,则它们组成一个逆序对

  • 假设数组为 nums[i]nums[j],若 i < j 并且 nums[i] > nums[j],则 (nums[i], nums[j]) 是一个逆序对。

目标是计算数组中这样的逆序对的数量。

示例

假设给定的数组为 [7, 5, 6, 4]。通过观察可以得到以下逆序对:

  • (7, 5)
  • (7, 6)
  • (7, 4)
  • (5, 4)
  • (6, 4)

总共有 5 对逆序对,因此最终结果为 5。

😃解题思路

直接使用双重循环暴力枚举每一对元素来检查是否为逆序对的复杂度为 O ( n 2 ) O(n^2) O(n2),这在数组规模较大时效率较低。为了解决这个问题,我们可以借助归并排序算法,通过将问题分解为更小的子问题来提高效率。

归并排序思想

归并排序是一种分治算法。它将一个大的问题分解为两个小的子问题,递归地解决子问题,最后将子问题的解合并成原问题的解。在计算逆序对时,我们可以通过在归并的过程中统计逆序对的数量,从而实现线性对数级别的时间复杂度 O ( n log ⁡ n ) O(n \log n) O(nlogn)

具体步骤

  1. 分解问题: 将数组分成左右两部分,分别对左右部分进行归并排序。
  2. 归并: 在归并的过程中,若左半部分的某个数字大于右半部分的某个数字,那么这个数字及左半部分后续的所有数字都比右半部分的数字大,形成逆序对。我们可以在归并的过程中统计这些逆序对。

💖代码实现

以下是基于归并排序来解决逆序对问题的Java代码实现:

private long cnt = 0;  // 用于计数逆序对的数量
private int[] tmp;  // 辅助数组,避免在递归过程中多次创建新数组public int InversePairs(int[] nums) {tmp = new int[nums.length];mergeSort(nums, 0, nums.length - 1);return (int) (cnt % 1000000007);  // 结果对1000000007取模,防止结果过大
}private void mergeSort(int[] nums, int l, int h) {if (h - l < 1)  // 当子数组的长度小于等于1时,不需要进行排序return;int m = l + (h - l) / 2;  // 计算中间位置mergeSort(nums, l, m);  // 递归排序左半部分mergeSort(nums, m + 1, h);  // 递归排序右半部分merge(nums, l, m, h);  // 合并排序后的两个子数组
}private void merge(int[] nums, int l, int m, int h) {int i = l, j = m + 1, k = l;  // 初始化左右指针和辅助数组的指针while (i <= m || j <= h) {  // 当左、右两部分数组未完全处理完时if (i > m) {tmp[k] = nums[j++];  // 左边处理完了,直接将右边的元素加入辅助数组} else if (j > h) {tmp[k] = nums[i++];  // 右边处理完了,直接将左边的元素加入辅助数组} else if (nums[i] <= nums[j]) {tmp[k] = nums[i++];  // 左边元素小于等于右边元素,加入辅助数组} else {tmp[k] = nums[j++];  // 右边元素小于左边元素,加入辅助数组cnt += m - i + 1;  // 统计逆序对,左边的剩余元素都比当前右边元素大}k++;}// 将辅助数组的结果复制回原数组for (k = l; k <= h; k++)nums[k] = tmp[k];
}

代码讲解

  1. cnt:用于计数逆序对的总数量。
  2. tmp:辅助数组,用于在归并时暂存排序后的子数组。
  3. InversePairs 方法:对输入数组调用归并排序,并返回逆序对数量。为了避免结果过大,返回时对 1000000007 取模。
  4. mergeSort 方法:实现归并排序的递归逻辑,将数组分为两部分,分别进行排序,并在排序过程中调用 merge 方法。
  5. merge 方法:实现两个已排序子数组的合并过程,同时统计逆序对的数量。若左边子数组的某个元素大于右边子数组的当前元素,则说明该元素与右边子数组当前元素及其后的所有元素都形成了逆序对。

时间复杂度分析

归并排序的时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组的长度。由于在归并的过程中我们只需额外进行 O ( n ) O(n) O(n) 的操作来统计逆序对,因此整个算法的时间复杂度仍然是 O ( n log ⁡ n ) O(n \log n) O(nlogn)。这比直接使用 O ( n 2 ) O(n^2) O(n2) 的双重循环要高效得多,特别是在数组规模较大时。

😄总结

逆序对问题是一个经典的算法问题,借助归并排序可以将其优化至 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间复杂度。通过在归并排序的过程中适时地统计逆序对,我们可以有效地解决这个问题。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

img

相关文章:

算法的学习笔记—数组中的逆序对(牛客JZ51)

&#x1f600;前言 在算法和数据结构领域&#xff0c;"逆序对"是一个经典问题。它在数组中两个数字之间定义&#xff0c;若前面的数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。我们要做的就是&#xff0c;给定一个数组&#xff0c;找出数组中所有的逆…...

Golang | Leetcode Golang题解之第498题对角线遍历

题目&#xff1a; 题解&#xff1a; func findDiagonalOrder(mat [][]int) []int {m, n : len(mat), len(mat[0])ans : make([]int, 0, m*n)for i : 0; i < mn-1; i {if i%2 1 {x : max(i-n1, 0)y : min(i, n-1)for x < m && y > 0 {ans append(ans, mat[x…...

什么是全局污染?怎么避免全局污染?

全局污染&#xff08;Global Pollution&#xff09;是指在编程过程中&#xff0c;过度使用全局变量或对象导致命名冲突、代码可维护性下降及潜在错误增加的问题。在 JavaScript 等动态语言中&#xff0c;尤其需要关注全局污染的风险。 全局污染的影响 1. 命名冲突 3. 意外修改…...

C# 串口通信教程

串口通信&#xff08;Serial Communication&#xff09;是一种用于设备之间数据传输的常见方法&#xff0c;通常用于与外部硬件设备&#xff08;如传感器、机器人、微控制器&#xff09;进行通信。在 C# 中&#xff0c;System.IO.Ports 命名空间提供了与串口设备交互的功能&…...

PHP编程基础

PHP&#xff08;Hypertext Preprocessor&#xff0c;超文本预处理器&#xff09;是一种广泛使用的开源服务器端脚本语言&#xff0c;主要用于网页开发&#xff0c;同时也可以进行命令行脚本编写。以下是PHP编程的基础知识&#xff1a; 1. PHP文件结构 PHP文件通常以 .php 为扩…...

TwinCAT3下位机配置EAP通讯传递与接收变量

添加EAP设备 DEVICE中右键选择添加新项&#xff0c;添加EAP&#xff08;EtherCAT Automation Protocal&#xff09;选择Network Variables类型&#xff0c;如下图。 设置网络适配器来激活EAP&#xff0c;在Adapter中选择search&#xff0c;选择网络适配器后确定&#xff0c;…...

近似推断 - 期望最大化(EM)篇

前言 近似推断是统计学和机器学习中一个至关重要的领域&#xff0c;尤其在处理复杂模型和不完全数据时显得尤为重要。期望最大化&#xff08; Expectation Maximization \text{Expectation Maximization} Expectation Maximization&#xff0c;简称 EM \text{EM} EM&#xff0…...

arp欺骗及其实验

ARP欺骗&#xff08;ARP Spoofing&#xff09;是一种网络攻击技术&#xff0c;攻击者通过伪造ARP&#xff08;地址解析协议&#xff09;消息&#xff0c;将其MAC地址与目标IP地址关联&#xff0c;从而实现对网络流量的截获、篡改或重定向。以下是ARP欺骗的详细信息&#xff1a;…...

HDU The Boss on Mars(容斥原理)

题目大意&#xff1a; ACM 有 n 名员工&#xff0c;现在是他们从老板那里拿薪水的时候了。所有员工都从 1 到 n 编号。原因不明&#xff0c;如果员工的工作编号是 k&#xff0c;他今年可以获得 k^4 Mars 美元。所以为 ACM 工作的员工非常富有。 因为员工人数太多&#xff0c;…...

nnUnet 大模型学习笔记(续):训练网络(3d_fullres)以及数据集标签的处理

目录 1. 数据集处理 1.1 实现脚本 1.2 json文件 2. 设置读取路径 2.1 设置路径 2.2 数据集转换 2.3 数据集预处理 2.4 训练&#xff08;3d_fullres) 3. 训练结果展示 关于nnUnet 数据集的处理和环境搭建&#xff0c;参考上文&#xff1a;第四章&#xff1a;nnUnet大模…...

Java中的数据结构与集合源码

目录 一、数据结构 1.1 数据结构概念 1.2 研究对象 1.3 常见存储结构 1.3.1 数组 1.3.2 链表 1.单向链表 2.双向链表 1.3.3 二叉树 1.3.4 栈&#xff08;FILO&#xff0c;先进后出&#xff09; 1.3.5 队列&#xff08;FIFO&#xff0c;先进先出&#xff09; 二、集合…...

Java应用程序的测试覆盖率之设计与实现(三)-- jacoco cli 客户端

一、背景 上文已把覆盖率数据采集好了&#xff0c;并提供远程连接的tcp地址及端口。 jacoco cli文档jacoco cli jar包 jacococli.jar 我下载好了&#xff0c;放在github工程里。 本文主要是介绍如何使用jacoco cli 客户端读取并生成覆盖率报告。 二、使用 1、dump覆盖率统…...

Deepin V23 / 统信UOS 下安装与配置 tftp

几个月前&#xff0c;我将开发系统从 ubuntu 切换到 Deepin&#xff0c;当时写过一篇文章《使用国产操作系统作为开发系统》。几个月下来&#xff0c;没有感觉有什么不适应&#xff0c;Ubuntu 能做的事情&#xff0c;在 Deepin 上都能做。而且有 UOS 应用商店的加持&#xff0c…...

java基础学习:定时任务常见实现方式

一、Timer解析 TaskQueue&#xff1a;小顶堆&#xff0c;存放timeTask。 TimerThread&#xff1a;任务执行线程 死循环不断检查是否有任务需要开始执行&#xff0c;有就执行它。始终是一个线程在执行。 单线程执行任务&#xff0c;任务有可能相互阻塞&#xff1a; schedul…...

句柄是什么?有什么用?举例说明

在C#编程中&#xff0c;“句柄”&#xff08;Handle&#xff09;是一个与操作系统资源相关联的标识符。句柄是一个指针或者索引&#xff0c;用于在程序代码中引用系统资源&#xff0c;如窗口、文件、线程等。由于直接操作这些资源非常危险且复杂&#xff0c;操作系统提供句柄作…...

Jenkins学习笔记

Jenkins学习笔记 NumTitleComments1官网 官方网站 中文文档2基础Jenkins基础3groovy1.groovy语法 2.groovy 入门4pipelinepipeline基本语法介绍5Github actiongithub action6Shared library1 2...

AI 解读软考高级操作系统顺序存取、直接存取、随机存取、相联存取的区别

这几个术语描述了不同类型的存储方式&#xff0c;它们涉及数据存取的顺序和灵活性。为了更好地理解&#xff0c;我们可以先通过生活中的例子来感受这些概念。 生活化例子 1. 顺序存取&#xff1a; 想象你在看一盘录像带&#xff08;比如老式的VHS录像带&#xff09;。如果你想…...

STM32烧写准备

目录 一.安装stlink驱动二.烧写器固件升级三.安装烧写程序四.进行测试1.流水灯 五.出现的问题1.升级固件问题2.测试时连接问题 一.安装stlink驱动 amd64是用在64位的&#xff0c;x86用在32位&#xff1b;双击运行即可 出现以下情况表示安装完成当连接上STM32开发板时&#xff…...

为Windows Terminal 配置zsh + Oh-My-Zsh!

参考&#xff1a; 为Windows Terminal 配置zsh Oh-My-Zsh! [非WSL] https://zhuanlan.zhihu.com/p/625583037 Package: zsh - MSYS2 Packages 安装配置 1、安装 Windows Terminal(必须) Method 1: 打开 Microsoft Store&#xff0c;搜索 “Windows Terminal”。点击 “…...

RNN、LSTM 与 Bi-LSTM

一. RNN 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是深度学习领域一类具有内部自连接的神经网络能够学习复杂的矢量到矢量的映射。 最大特点&#xff1a;前面的序列数据可以用作后面的结果预测中。 一个简单的循环神经网络结构&#xff0c;其结构包…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...

mq安装新版-3.13.7的安装

一、下载包&#xff0c;上传到服务器 https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz 二、 erlang直接安装 rpm -ivh erlang-26.2.4-1.el8.x86_64.rpm不需要配置环境变量&#xff0c;直接就安装了。 erl…...