后端开发刷题 | 数组中的逆序对

news/2024/9/20 1:30:17/ 标签: 算法, 数据结构, java, 开发语言, 排序算法

描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围:  对于 50%50% 的数据, size≤104
对于 100%100% 的数据, size≤105

数组中所有数字的值满足 0≤val≤109

要求:空间复杂度 O(n),时间复杂度 O(nlogn)

输入描述:

题目保证输入的数组中没有的相同的数字

示例1

输入:

[1,2,3,4,5,6,7,0]

返回值:

7

示例2

输入:

[1,2,3]

返回值:

0

思路分析:

利用归并排序(Merge Sort)的分治思想,在归并排序的合并过程中计算逆序对的数量。归并排序将数组分成两半,递归地对这两半进行排序,然后将排序好的两半合并成一个有序数组。在这个过程中,我们可以统计跨越分割点的逆序对数量。

详细步骤

  1. 分解
    • 如果数组只有一个元素或为空,则不需要排序,也没有逆序对,直接返回。
    • 否则,找到数组的中间位置,将数组分成左右两个子数组。
    • 递归地对左子数组和右子数组进行分解和排序,并计算它们各自的逆序对数量(这些逆序对不会跨越两个子数组之间的分割点)。
  2. 合并与计算逆序对
    • 创建一个临时数组用于合并两个已排序的子数组。
    • 初始化三个指针:i 指向左子数组的起始位置,j 指向右子数组的起始位置,k 指向临时数组的起始位置。
    • 遍历两个子数组,比较 left[i] 和 right[j] 的大小:
      • 如果 left[i] <= right[j],说明 left[i] 及其之前的所有元素都不会与 right[j] 及其之后的元素形成逆序对,因此可以安全地将 left[i] 放入临时数组,并递增 i 和 k
      • 如果 left[i] > right[j],则说明 left[i] 与 right[j] 到 right[rightEnd](右子数组的末尾)之间的所有元素都形成了逆序对。因此,将逆序对数量增加 rightEnd - j + 1(右子数组中剩余的元素数量),并将 right[j] 放入临时数组,递增 j 和 k
    • 重复上述过程,直到一个子数组的所有元素都被放入临时数组。
    • 将另一个子数组中剩余的元素(如果有的话)直接复制到临时数组的末尾。
  3. 返回结果
    • 在合并过程中,累加跨越分割点的逆序对数量。
    • 当整个数组被合并成一个有序数组时,返回累计的逆序对数量(取模以防止溢出)。
图例:

代码:

java">import java.util.*;public class Solution {int mod = 1000000007;public int mergeSort(int left, int right, int[] data, int[] temp) {//如果 left 大于等于 right,表示没有元素或只有一个元素,无需排序和计算逆序对,直接返回 0if (left >= right) {return 0;}int mid = (left + right) / 2;//递归地对左半部分和右半部分进行排序并计算逆序对数量,将结果相加并取模。int res = mergeSort(left, mid, data, temp) + mergeSort(mid + 1, right, data,temp);res %= mod;int i = left, j = mid + 1;//使用临时数组 temp 来辅助合并两个已排序的部分,并在合并过程中计算逆序对。for (int k = left; k <= right; k++) {temp[k] = data[k];}for (int k = left; k <= right; k++) {//当左边已经遍历完(i == mid +1),直接将右边剩余的元素复制到 data 中。if (i == mid + 1) {data[k] = temp[j++];} else if (j == right + 1 || temp[i] <= temp[j]) {//如果右边已经遍历完或左边当前元素小于等于右边当前元素,将左边当前元素复制到data 中。data[k] = temp[i++];} else {//如果左边当前元素大于右边当前元素,则将右边当前元素复制到//data 中,并增加逆序对计数(因为左边剩余的所有元素(mid -i + 1)都大于右边当前元素,形成逆序对)。data[k] = temp[j++];res += mid - i + 1;}}return res%mod;}/*** @param nums int整型一维数组* @return int整型*/public int InversePairs (int[] nums) {int n=nums.length;int[] res=new int[n];return mergeSort(0,n-1,nums,res);}
}


http://www.ppmy.cn/news/1521289.html

相关文章

JavaWeb - Mybatis入门

MySQL的客户端命令行&#xff0c;如何来连接服务器上部署的MySQL &#xff1a; mysql -u 用户名 -p 密码 [-h 数据库服务器的 IP 地址 -P 端口号 ] Mybatis 做为后端程序开发人员&#xff0c;通常会使用 Java 程序来完成对数据库的操作。 Java 程序操作数据库&#xff0c;现 …

C#基础(2)枚举

前言 我们其实在前面已经了解过枚举到底有什么作用&#xff0c;但是那毕竟是概念性的语言&#xff0c;理解起来很抽象&#xff0c;今天我们会具体来讲一讲枚举&#xff0c;并谈一谈它的应用。 希望你能从今天的C#基础中有所收获。 基本概念 1.枚举&#xff1a;是一个比较特…

Ubuntu22.04版本左右,开机自动启动脚本

Ubuntu22.04版本左右&#xff0c;开机自动启动脚本 1. 新增/lib/systemd/system/rc-local.service中[Install]内容 vim /lib/systemd/system/rc-local.service 按 i 进入插入模式后&#xff0c;新增内容如下&#xff1a; [Install] WantedBymulti-user.target Aliasrc-local.…

Android终端如何快速接入GB28181平台实现实时音视频回传

技术背景 GB28181是由中国国家标准委员会发布的基于IP网络的安防视频监控标准。Android平台GB28181设备对接模块&#xff0c;主要涉及到视频监控领域&#xff0c;可实现不具备国标音视频能力的 Android终端&#xff0c;通过平台注册接入到现有的GB/T28181—2016服务&#xff0…

Prometheus(八):Prometheus监控elasticsearch及常用API

目录 1 Prometheus监控elasticsearch1.1 启动ES自带的监控模块暴露指标数据1.2 通过Prometheus的插件 Elasticsearch Exporter来获取指标数据1、简介2、安装3、Prometheus配置 2 Prometheus常用API2.1 查询2.2 删除2.3 注册服务 1 Prometheus监控elasticsearch 使用Prometheus…

AI在医学领域:基础模型和视觉-语言模型在计算病理学应用概述

近年来&#xff0c;人工智能&#xff08;AI&#xff09;基于方法在计算病理学&#xff08;CPath&#xff09;领域中的应用迅速增长&#xff0c;这主要得益于数字幻灯片扫描仪的广泛采用。因此&#xff0c;大规模的全幻灯片图像&#xff08;Whole Slide Images, WSIs&#xff09…

盘点4款超好用的电脑数据恢复工具

如今我们的生活和工作越来越离不开电脑&#xff0c;因此电脑里面也储存了我们大量的数据&#xff1a;图片&#xff0c;文档&#xff0c;工作资料等。但是这些重要数据却会因为误删除、病毒攻击、系统崩溃等原因遭到丢失。所以数据恢复软件就变得十分的重要&#xff0c;今天&…

零基础转行学网络安全怎么样?

&#x1f91f; 基于入门网络安全打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 如果您对转行学习网络安全感兴趣&#xff0c;以下是一些分析和建议&#xff1a; 一、网络安全行业的前景 网络安全行业作为一个新兴且不断发展的领域&#xff0c;具…

天润融通解开售后维修的成本枷锁,提高维修服务效率

如今&#xff0c;企业客户服务在开展业务咨询和售后受理时&#xff0c;主要方式还是通过电话与在线方式进行。这种方式虽然方便&#xff0c;但是对于一些非常紧急的情况还是显得有些不够。 比如&#xff0c;虽然现在许多企业APP已经实现了一键咨询和一键报修&#xff0c;但当客…

基于JAVA+SpringBoot+Vue的大学校园回忆录系统

基于JAVASpringBootVue的大学校园回忆录系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; …

vscode +STM32 VS CODE EXTENSION

stm32 vs code extersion 1.0.0版本可以直接导入cubeide的工程&#xff0c;之后版本不可以&#xff0c;所以为了省事&#xff0c;使用stm32 vs code extersion 1.0.0插件。 安装完stm32 vs code extersion插件&#xff0c;会默认把相关插件一起安装。但是需要手动安装Ninja&am…

Nginx: TCP建立连接的优化和启用Fast Open功能

TCP 建立连接优化 在三次握手中&#xff0c;相关TCP的内核参数可优化这一过程 net.ipv4.tcp_syn_retries 6net.ipv4.tcp_synack_retries 5net.ipv4.tcp_syncookies 0net.ipv4.tcp_max_syn_backlognet.core.somaxconnnet.core.netdev_max_backlog 1 &#xff09; net.ipv4…

HTTP 之 消息结构(二十二)

HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档的协议&#xff0c;它定义了客户端和服务器之间请求和响应的消息结构。HTTP消息由一系列标准头部字段、一个空行和可选的消息体组成。 客户端请求消息 请求消息包括以下格式&#xff1a;请求行&#xff08;…

VR虚拟驾驶未来发展_vr自动驾驶汽车所带来的改变

在自动驾驶汽车的基础上&#xff0c;VR虚拟现实技术的应用也让自动驾驶汽车更加智能化&#xff0c;能够实现更高级的驾驶体验&#xff0c;今天这篇文章就和大家一起探讨一下 VR虚拟驾驶未来发展的趋势&#xff0c;以及虚拟现实自动驾驶汽车所带来的几个改变。 一、VR 虚拟驾驶未…

hadoop的sbin

路径&#xff1a;opt/homebrew/sbin Hadoop 的 sbin 目录下包含了一系列 shell 脚本&#xff0c;用于启动、停止和管理 Hadoop 的各个组件和服务。下面逐一解释这些脚本的作用&#xff1a; 启动和停止脚本 start-all.sh 用于启动所有的 Hadoop 守护进程&#xff0c;包括 Name…

Qt-高DPI显示器

与标准DPI显示器相比&#xff0c;高DPI显示器增加了像素密度。 像素密度以每英寸点数(DPI)或每英寸像素(PPI)来衡量&#xff0c;由显示像素的数量和它们的大小决定。因此&#xff0c;单独的像素数量不足以确定显示器是否属于高dpi类别。 4K显示器有固定的像素数(约8米)&#x…

【时时三省】(C语言基础)指针进阶 例题2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 第一个arr 数组名相当于首元素地址 因为他没有放到strlen内部 也没有取地址 strlen是找&#xff3c;0 找不到&#xff3c;0就不会停下来 所以它打印的就是随机值 第二个arr0 首元素地址加零还…

C++ 图形框架 Duilib

Duilib是一个开源的DirectUI界面库&#xff0c;遵循BSD协议&#xff0c;可以免费用于商业项目。它具有以下特点&#xff1a; 简约易扩展的设计&#xff1a;Duilib遵循简洁、清晰的设计理念&#xff0c;使得用户界面更加直观、易于使用。同时&#xff0c;它也提供了丰富的扩展接…

镭速传输助力汽车行业打造安全高效的大文件传输新纪元

在数字化浪潮的推动下&#xff0c;汽车行业正迈向智能化和互联互通的新阶段&#xff0c;这对数据传输和管理提出了更高标准。大文件的快速传输、长距离传输的效率、跨国数据的合规性与安全性、以及数据脱敏需求等&#xff0c;成为汽车企业数字化转型中必须面对的挑战。 传输效率…

达梦数据库-DM8 企业版安装指南

一、DM8 企业版简介 达梦数据库(DM8)是中国自主研发的一款高性能数据库管理系统,广泛应用于企业级应用场景。DM8 企业版具备高可用性、强一致性和高性能等特点,支持多种操作系统和硬件平台。本文将详细介绍如何在 Kylin 操作系统上安装达梦数据库 DM8 企业版。 二、安装前…