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

2023-12-05

在这里插入图片描述

????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 + 1 cur2++

所以,这个时间复杂度就和归并排序的时间复杂度一模一样 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 关于svn如何上传一个完整的项目

    注意 请一定要按照该步骤进行操作 请上传新项目时将项目名称进行规范命名 例如原始文件是arrange v2 将此项目需要注入新的医院 则命名为 arrange 某医院名称 门诊或者医技或者药房 v2 重新命名文件夹名称快捷键 F12 一 先
  • 目标检测算法改进系列之添加SCConv空间和通道重构卷积

    SCConv 空间和通道重构卷积 SCConv 空间和通道重构卷积 的高效卷积模块 以减少卷积神经网络 CNN 中的空间和通道冗余 SCConv旨在通过优化特征提取过程 减少计算资源消耗并提高网络性能 该模块包括两个单元 1 空间重构单元
  • 自动化测试的4大注意事项

    自动化测试能够提高测试效率 覆盖率 降低测试成本和工作量 是软件开发中不可或缺的一部分 但前提是要确保自动化测试的有效性和可靠性 否则无效或错误的自动化测试 往往会对项目造成负面影响 如维护成本高 假阳性和假阴性等问题 因此我们在进行自动化

随机推荐

  • 给出employees表中排名为奇数行的first_name

    给出employees表中排名为奇数行的first name select e first name first from employees e join select first name row number o 题解 二叉树中和为某
  • 头歌—密码学基础

    第1关 哈希函数 题目 任务描述 本关任务 利用哈希算法统计每个字符串出现的个数 相关知识 为了完成本关任务 你需要掌握 1 密码学哈希函数的概念及特性 2 安全哈希算法 密码学哈希函数的概念及特性 我们需要理解的第一个密码学的基础知识是密
  • EasyRecovery易恢复2024最新免费版电脑数据恢复软件功能介绍

    EasyRecovery从 易恢复2024 支持恢复不同存储介质数据 在Windows中恢复受损和删除文件 以及能检索数据格式化或损坏卷 甚至还可以从初始化磁盘 同时 你只需要最简单的操作就可以恢复数据文件 如 硬盘 光盘 U盘 移动硬盘
  • 用Python手把手教你实现一个爬虫(含前端界面)

    目录 前言 爬虫基本原理 使用Python的requests库发送HTTP请求 使用BeautifulSoup库解析HTML页面 使用PyQt5构建前端界面 实现一个完整的爬虫程序 结语 前言 随着互联网的飞速发展 再加上科技圈的技术翻天覆
  • FL Studio2024水果编曲软件21.2.0中文版本下载更新

    FL Studio2024是功能强大的音乐制作解决方案 使用旨在为用户提供一个友好完整的音乐创建环境 让您能够轻松创建 管理 编辑 混合具有专业品质的音乐 一切的一切都集中在一个软件中 只要您想 只要您需要 它总能满足您的音乐需求 工具方面
  • 拼多多财报解读:连接高质量供给与全球消费者,多多跨境动力澎湃

    题解 牛牛的排序 include
  • 链表【1】

    文章目录 2 两数相加 1 题目 2 算法原理 3 代码实现 445 两数相加 II
  • FL Studio21.2.0中文完整版Crack

    Fl Studio21是最好的音乐制作软件 但它的成本超过300美元 一个年轻的新音乐创作者怎么能从上到下 地球上没有比 FL Studio 21 更完整的音乐制作软件了 14 年来 它一直是行业领导者 并且随着随后的每一次更新 在此之前已
  • 最后一次改简历了,麻烦牛客的大佬们最后指导我一下吧

    题解 操作符混合运用 SELECT device id gender age university gpafrom user profilewhere gpa in 3 5 3 8 京东实习 全程1H 记录一下1 自我介绍2 介绍项目亮点3
  • 牛客周赛 Round 22 解题报告 | 珂学家 | 思维构造 + 最小生成树

    题解 提取不重复的整数 import java util HashSet import java util Scanner 注意类名必须为 Main 不要有任何 package 题解 计算三角形的周长和面积 include
  • 链表【2】

    文章目录 24 两两交换链表中的节点 题目 算法原理 代码实现 143 重排链表
  • 谈谈 .NET8 平台中对 LiteDB 的 CRUD 操作

    哪个啥 纯 C 编写的 LiteDB 你还不会操作 LiteDB 简介 LiteDB 安装 1 同步版 LiteDB 2 异步版 LiteDB Async LiteDB Studio LiteDB CRUD 操作举例 1 net cli 命
  • 【LeetCode:1423. 可获得的最大点数 | 滑动窗口】

    算法题 算法刷题专栏 面试必备算法 面试高频算法 越难的东西 越要努力坚持 因为它具有很高的价值 算法就是这样 作者简介 硕风和炜 CSDN Java领域新星创作者 保研 国家奖学金 高中学习JAVA 大学完善JAVA开发技术栈 面试刷题
  • LeetCode:1038. 从二叉搜索树到更大和树(反向中序遍历 C++、Java)

    目录 1038 从二叉搜索树到更大和树 题目描述 实现代码与解析 dfs 原理思路 1038 从二叉搜索树到更大和树 题目描述 给定一个二叉搜索树 root BST 请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和 提醒一
  • SSM 线上知识竞赛系统-计算机毕设 附源码 27170

    SSM线上知识竞赛系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化 电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用 信息时代的到来已成为不可阻挡的时尚潮流 人类发展的历史正进入一个新时代 在现实运用中 应
  • FL Studio2024中文语言版水果编曲软件

    FL Studio21 2这款软件在国内被广泛使用 因此又被称为 水果 它提供音符编辑器 可以针对作曲者的要求编辑出不同音律的节奏 例如鼓 镲 锣 钢琴 笛 大提琴 筝 扬琴等等任何乐器的节奏律动 此外 它还提供了方便快捷的音源输入 对于在
  • “丝路电商”与泛欧在线公共采购平台Peppol

    近期上海商务委员会公布 关于在上海市创建 丝路电商 合作先行区的方案 以下简称方案 方案中提出 全面贯彻落实党的二十大精神 立足新发展阶段 完整 准确 全面贯彻新发展理念 加快构建新发展格局 统筹发展和安全 发挥上海在改革开放中的突破攻坚作
  • Springboot养老院信息管理系统的开发-计算机毕设 附源码 27500

    Springboot养老院信息管理系统的开发 摘 要 随着互联网趋势的到来 各行各业都在考虑利用互联网将自己推广出去 最好方式就是建立自己的互联网系统 并对其进行维护和管理 在现实运用中 应用软件的工作规则和开发步骤 采用Springboo
  • 分治—快速选择算法

    文章目录 215 数组中的第K个最大元素 1 题目 2 算法原理 3 代码实现 LCR 159 库存管理 III
  • 分治-归并算法——LCR 170. 交易逆序对的总数

    文章目录 0 归并排序 1 题目 2 算法原理 3 代码实现 0 归并排序 归并排序是典型的分治 将数组分成若干个子数组 数组两两比较 不是很清楚的 可以查看此篇文章 数据结构 七大排序 这里以力扣 9