分治-归并算法——LCR 170. 交易逆序对的总数

news2025/1/23 9:05:50

在这里插入图片描述

文章目录

    • 🌼0. 归并排序
    • 🌻1. 题目
    • 🌼2. 算法原理
    • 🌷3. 代码实现

🌼0. 归并排序

归并排序是典型的分治,将数组分成若干个子数组,数组两两比较,不是很清楚的,可以查看此篇文章——数据结构——七大排序

这里以力扣912. 排序数组为例:

class Solution {
    vector<int> tmp;
public:
    vector<int> sortArray(vector<int>& nums)
    {
        tmp.resize(nums.size());
        mergeSort(nums, 0, nums.size()-1);
        return nums;
    }

    void mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)   return;
        int mid = left + (right-left)/2;
        //[left,mid] [mid+1,right]
        mergeSort(nums,left,mid);
        mergeSort(nums,mid+1,right);
        //合并
        int i = 0,
            cur1 = left,
            cur2 = mid+1;
        while(cur1 <= mid && cur2 <= right)
            tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];
        //检查没有遍历完的数组
        while(cur1 <= mid)  tmp[i++] = nums[cur1++];
        while(cur2 <= right)    tmp[i++] = nums[cur2++];
        //还原到原数组
        for(int i = left; i <= right; i++)  nums[i] = tmp[i-left];

    }
};

🌻1. 题目

题目链接:LCR 170. 交易逆序对的总数

在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 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

🌼2. 算法原理

逆序对的意思就是,从数组中挑2个数,前面的数大于后面的数 且 前一个数的下标小于后一个数的下标,然后查看有几对

解法一:暴力枚举

固定一个数,找后面的区间,两层for循环即可,但是这个题目的等级是困难,对于力扣的题目等级划分,简单题基本可采用暴力解法,但是在中等及困难这两个等级,暴力解法大部分都是行不通的。

解法一:归并

如果要求整个数组的逆序对,我们可以将数组分为两部分,先求左边区域的逆序对,再求右边区域的逆序对,然后左边选一个、右边选一个,看看这样有多少个逆序对,这个的本质其实还是属于暴力枚举

image-20231203121210300

我们在此想法是再优化一下,即当左边区域挑选完毕之后,对左区域排序;右边区域挑选完毕之后,对右区域排序,然后再挑选,一左一右挑选完毕之后,再排一下序,这个过程就和归并排序的过程一样了。

为什么归并会快(升序为例)?

image-20231203122144250

我们固定一个数,要找出有多少个数比这个数大,在上图,我们看对于cur2,在左区间有多少个数比这个数大,这样就和归并排序完美契合,分3种情况:

  1. nums[cur1] <= nums[cur2]–>cur1++<=情况操作一样)
  2. nums[cur1] > nums[cur2] ,此时cur1后面的元素全部大于nums[cur2],然后就能直接统计出一大堆ret += mid - cur1 + 1cur2++

所以,这个时间复杂度就和归并排序的时间复杂度一模一样O(N*logN)

细节问题:

刚刚是以升序为例,如果采用降序,即找出该数之后,有多少个小于该数的元素

image-20231203124001251

🌷3. 代码实现

升序:

class Solution {
    int tmp[50001];
public:
    int reversePairs(vector<int>& record)
    {
        return mergeSort(record,0,record.size()-1);
    }

    int mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)   return 0;
        
        int ret = 0;
        int mid = (left + right) >> 1;
        
        //[left,mid]  [mid+1,right]
        //左边逆序对个数 排序
        //右边逆序对个数 排序
        ret += mergeSort(nums,left,mid);
        ret += mergeSort(nums,mid+1,right);

        //一左一右个数
        int cur1 = left,
            cur2 = mid+1,
            i = 0;
        while(cur1 <= mid && cur2 <= right)
        {
            if(nums[cur1] <= nums[cur2])    tmp[i++] = nums[cur1++];
            else
            {
                ret += mid - cur1 + 1;
                tmp[i++] = nums[cur2++];
            }
        }

        //排序
        while(cur1 <= mid)  tmp[i++] = nums[cur1++];
        while(cur2 <= right)    tmp[i++] = nums[cur2++];
        for(int i = left; i <= right; i++)  nums[i] = tmp[i-left];
        return ret;
    }
};

降序:

class Solution {
    int tmp[50001];
public:
    int reversePairs(vector<int>& record)
    {
        return mergeSort(record,0,record.size()-1);
    }

    int mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)   return 0;
        
        int ret = 0;
        int mid = (left + right) >> 1;
        
        //[left,mid]  [mid+1,right]
        //左边逆序对个数 排序
        //右边逆序对个数 排序
        ret += mergeSort(nums,left,mid);
        ret += mergeSort(nums,mid+1,right);

        //一左一右个数
        int cur1 = left,
            cur2 = mid+1,
            i = 0;
        while(cur1 <= mid && cur2 <= right)
        {
            if(nums[cur1] <= nums[cur2])    tmp[i++] = nums[cur2++];
            else
            {
                ret += right - cur2 + 1;
                tmp[i++] = nums[cur1++];
            }
        }

        //排序
        while(cur1 <= mid)  tmp[i++] = nums[cur1++];
        while(cur2 <= right)    tmp[i++] = nums[cur2++];
        for(int i = left; i <= right; i++)  nums[i] = tmp[i-left];
        return ret;
    }
};

运行结果:

image-20231203125139503

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

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

相关文章

VUE设计与实现共读系列之ref的实现【响应式原理】

前言 我们先顺一下vue使用响应式数据的流程&#xff1a; vue 是通过 ref 和 reactive 来创建响应式值&#xff0c;改变响应式值&#xff0c;视图跟着发生变化。 我们今天就来看一下ref和reactive是如何实现的 准备 首先&#xff0c;打开ref函数的位置 我们可以看到一个被re…

10行代码实现vue路由最简单的登陆拦截

需求&#xff1a;不涉及任何角色权限&#xff0c;基本实现目标&#xff0c;有token就可查看任何页面&#xff0c;否则就去登陆&#xff0c;来一步步实现 1. 创建你的路由页面&#xff0c;此处略了 2. 导航守卫拦截判断思路 // 创建路由 const router createRouter({history…

Python----字典练习

相关链接&#xff1a;Python---字典的增、删、改、查操作_python中字典的增删改查-CSDN博客 Python---字典---dict-CSDN博客 Python---引用变量与可变、非可变类型-CSDN博客 重点&#xff1a; 字典中的 key &#xff08;就是键&#xff09;可以是很多数据类型&#xff08;…

对比ProtoBuf和JSON的序列化和反序列化能力

1.序列化能力对比验证 在这里让我们分别使用PB与JSON的序列化与反序列化能力&#xff0c;对值完全相同的一份结构化数据进行不同次数的性能测试。 为了可读性&#xff0c;下面这一份文本使用JSON格式展示了需要被进行测试的结构化数据内容: {"age" : 20,"name…

SpringAMQP入门案例——接收消息

依赖 <!--SpringAMQP起步依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> yml配置文件 自行修改 spring:rabbitmq:host: 192.168.220.130 # …

Spring MVC学习随笔-控制器(Controller)开发详解:接受客户端(Client)请求参数

学习视频&#xff1a;孙哥说SpringMVC&#xff1a;结合Thymeleaf&#xff0c;重塑你的MVC世界&#xff01;&#xff5c;前所未有的Web开发探索之旅 第三章、SpringMVC控制器开发详解 3.1 核心要点 &#x1f4a1; 1. 接受客户端&#xff08;client&#xff09;请求参数[讲解] 2…

Linux脚本awk命令

目录 一. awk命令简介 1. awk版本 2. awk与vim的区别 3. awk与sed的区别 4. awk工作原理 5. awk格式 6. awk常用选项 二. awk基础用法 1. awk基础用法 2. BEGIN和END语句块 3. 指定分隔符 4. 首尾关键字 三. awk内置变量 1. FS变量 2. OFS变量 3. RS变量 4. NF…

【Unity动画】为一个动画片段添加事件Events

动画不管播放到那一帧&#xff0c;我们都可以在这里“埋伏”一个事件&#xff08;调用一个函数并且给函数传递一个参数&#xff0c;参数在外部设置&#xff0c;甚至传递一个物体&#xff09;&#xff01; 嗨&#xff0c;亲爱的Unity小伙伴们&#xff01;你是否曾想过为你的动画…

语言模型文本处理基石:Tokenizer简明概述

编者按&#xff1a;近年来&#xff0c;人工智能技术飞速发展&#xff0c;尤其是大型语言模型的问世&#xff0c;让 AI 写作、聊天等能力有了质的飞跃。如何更好地理解和利用这些生成式 AI&#xff0c;成为许多开发者和用户关心的问题。 今天&#xff0c;我们推出的这篇文章有助…

【小沐学Python】网络爬虫之lxml

文章目录 1、简介2、安装3、基本功能3.1 lxml.etree3.2 解析HTML网页3.3 读取并解析HTML文件3.4 提取所有a标签内的文本信息3.5 树迭代3.6 序列化3.7 元素以字典的形式携带属性3.8 元素包含文本 4、代码测试4.1 lxml解析网页4.2 使用xpath获取所有的文本4.3 使用xpath获取 clas…

TA-Lib学习研究笔记(二)——Overlap Studies上

TA-Lib学习研究笔记&#xff08;二&#xff09;——Overlap Studies 1. Overlap Studies 指标 [BBANDS, DEMA, EMA, HT_TRENDLINE, KAMA, MA, MAMA, MAVP, MIDPOINT, MIDPRICE, SAR, SAREXT, SMA, T3, TEMA, TRIMA, WMA]2.数据准备 get_data函数参数&#xff08;代码&#x…

mongoose学习记录

mongoose安装和连接数据库 npm i mongoose导入mongoose const mongoose require(mongoose) mongoose.set("strictQuery",true)连接数据库 mongoose.connect(mongodb:127.0.0.1:27017/test)设置回调 mongoose.connection.on(open,()>{console.log("连接成…

利用段落检索和生成模型进行开放域问答12.2

利用段落检索和生成模型进行开放域问答 摘要引言2 相关工作3 方法 摘要 事实证明&#xff0c;开放域问答的生成模型具有竞争力&#xff0c;无需借助外部知识。虽然很有希望&#xff0c;但这种方法需要使用具有数十亿个参数的模型&#xff0c;而这些模型的训练和查询成本很高。…

还在Wins 11怀念10的右键单击菜单?别担心,可通过注册表来实现

到目前为止&#xff0c;Windows 11最令人讨厌的新“功能”是右键单击任何内容时会出现截断的上下文菜单。以前版本的Windows显示了你的所有选项&#xff0c;包括可以打开文件的不同程序&#xff0c;而新菜单仅限于少数选项&#xff0c;不一定是你想要的。 例如&#xff0c;当我…

SHAP(五):使用 XGBoost 进行人口普查收入分类

SHAP&#xff08;五&#xff09;&#xff1a;使用 XGBoost 进行人口普查收入分类 本笔记本演示了如何使用 XGBoost 预测个人年收入超过 5 万美元的概率。 它使用标准 UCI 成人收入数据集。 要下载此笔记本的副本&#xff0c;请访问 github。 XGBoost 等梯度增强机方法对于具有…

C++ day48 打家劫舍

题目1&#xff1a;198 打家劫舍 题目链接&#xff1a;打家劫舍 对题目的理解 专业小偷偷盗房屋的钱财&#xff0c;每个房屋存放的金额用非负整数数组表示&#xff1b; 如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警&#xff1b; 不触动警报装置的情况…

吸积效应:为什么接口会越来越臃肿?我们从一个接口说起

欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章&#xff0c;主要包括源码分析、实际应用、架构思维、职场分享、产品思考等等&#xff0c;同时欢迎大家加我微信「java_front」一起交流学习 1 从一个接口说起 1.1 初始接口 假设现在有一个创建订单接口&#xff1a; pub…

C语言每日一题(44)删除排序链表中的重复元素 II

力扣 82 删除排序链表中的重复元素 II 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示…

mac安装解压缩rar后缀文件踩坑

mac默认能够解压缩zip后缀的文件&#xff0c;如果是rar后缀的自己需要下载相关的工具解压 下载地址&#xff1a; https://www.rarlab.com/download.htm mac我是因特尔芯片所以下载 x64 然后解压缩文件进入目录 rar中 将可执行文件 rar、unrar 移动到 /usr/local/bin目录下即…

【高效开发工具系列】jackson入门使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…