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

【算法】分治:归并排序之LCR 170.交易逆序对的总数(hard)

系列专栏

双指针

模拟算法

分治思想


目录

1、题目链接

2、题目介绍

3、解法

4、代码


1、题目链接

LCR 159. 库存管理 III - 力扣(LeetCode)

2、题目介绍

在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。

示例 1:

输入:record = [9, 7, 5, 4, 6]
输出:8
解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。

限制:

0 <= record.length <= 50000

3、解法

  1. 逆序对的计算
    在归并排序的合并步骤中,当我们将两个已排序的子数组合并成一个有序数组时,如果左侧子数组中的某个元素大于右侧子数组中的某个元素,那么左侧子数组中该元素之后的所有元素(包括该元素本身)都将与右侧子数组中的该元素形成逆序对。因此,我们可以通过计算这样的元素对数来统计逆序对的总数。

  2. 具体实现

    • 分割:将数组分成左右两部分,递归地对它们进行排序。
    • 合并与计数:在合并过程中,使用两个指针分别指向左右子数组的起始位置,比较两个指针所指向的元素。如果左侧元素大于右侧元素,则左侧元素及其之后的所有元素都将与右侧当前元素形成逆序对,因此逆序对数增加 mid - cur1 + 1mid 是左右子数组的分界点,cur1 是左侧子数组的当前指针位置)。然后,将较小的元素放入临时数组 tmp 中,并移动相应的指针。
    • 复原:将临时数组 tmp 中的元素复制回原数组 record,以完成排序和逆序对的计算。
    • 时间复杂度:归并排序的时间复杂度为 O(n log n),其中 n 是数组的长度。在合并过程中,我们遍历了每个元素一次,因此计算逆序对的额外时间复杂度也是 O(n log n)。
    • 空间复杂度:归并排序需要额外的空间来存储临时数组 tmp,其大小为 n,因此空间复杂度为 O(n)。

4、代码

//归并排序
//升序
class Solution {vector<int> tmp;
public:int reversePairs(vector<int>& record) {tmp.resize(record.size());return mergeSort(record, 0, record.size() - 1);}// 查找区间内的逆序对总数(归并排序思想)int mergeSort(vector<int>& record, int left, int right){if (left >= right) return 0;// 1. 找中点将数组分成两部分// [left,mid] [mid+1,right]int mid = (right - left) / 2 + left;int ret = 0;// 2. 左边的个数 + 排序 ,右边的个数 + 排序ret += mergeSort(record, left, mid);ret += mergeSort(record, mid + 1, right);// 3. 一左一右的个数(升序版本)int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right){if (record[cur1] <= record[cur2]) tmp[i++] = record[cur1++];else{ret += mid - cur1 + 1;//合并过程中计数,逆序对tmp[i++] = record[cur2++];}}// 4. 处理排序过程while (cur1 <= mid) tmp[i++] = record[cur1++];while (cur2 <= right) tmp[i++] = record[cur2++];// 复原for (int i = left; i <= right; i++)record[i] = tmp[i - left];return ret;}
};

💗感谢阅读!💗

相关文章:

  • linux脚本工具
  • 【Godot4.3】简单物理模拟之圆粒子碰撞检测
  • 【Java】虚拟机(JVM)内存模型全解析
  • RM服务器研究(一)
  • SpringBoot3.X配置OAuth
  • vLLM (6) - Scheduler BlockSpaceManager
  • 数据结构:栈 及其应用
  • 多元函数微分学基础题
  • 【开源免费】基于SpringBoot+Vue.JS服装销售平台(JAVA毕业设计)
  • 【C++】二义性
  • ffmpeg拉取rtsp网络视频流报错解析
  • 学校周赛(2)
  • 如何在银河麒麟操作系统中查看内存页大小
  • 大数据Hologres(一):Hologres 简单介绍
  • 【数据结构初阶】排序算法(中)快速排序专题
  • Google 是如何开发 Web 框架的
  • 【Leetcode】104. 二叉树的最大深度
  • Android 控件背景颜色处理
  • docker python 配置
  • HTML-表单
  • javascript面向对象之创建对象
  • JavaScript新鲜事·第5期
  • Kibana配置logstash,报表一体化
  • pdf文件如何在线转换为jpg图片
  • React的组件模式
  • Tornado学习笔记(1)
  • underscore源码剖析之整体架构
  • vue 配置sass、scss全局变量
  • 关于extract.autodesk.io的一些说明
  • 关于springcloud Gateway中的限流
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 精彩代码 vue.js
  • 扑朔迷离的属性和特性【彻底弄清】
  • 线性表及其算法(java实现)
  • 通过调用文摘列表API获取文摘
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #{} 和 ${}区别
  • (23)mysql中mysqldump备份数据库
  • (55)MOS管专题--->(10)MOS管的封装
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (剑指Offer)面试题34:丑数
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)Dubbo快速入门、介绍、使用
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • *Django中的Ajax 纯js的书写样式1
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .htaccess配置重写url引擎
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .Net 访问电子邮箱-LumiSoft.Net,好用