数据结构笔记--归并排序及其拓展题(小和问题、逆序对问题)

news2024/10/5 15:06:54

目录

1--归并排序

2--小和问题

3--逆序对问题


1--归并排序

        归并排序的核心思想:将一个无序的序列归并排序为一个有序的系列;通过递归将无序的序列二分,从底层开始将二分的序列归并排序为有序序列;

#include <iostream>
#include <vector>

class Solution{
public:
    std::vector<int> Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return arr;
        split(arr, 0, arr.size() - 1);
        return arr;
    }

    // 二分
    void split(std::vector<int> &arr, int l, int r){
        if(l == r) return;
        int mid = l + (r - l) / 2;
        split(arr, l, mid);
        split(arr, mid+1, r);
        // 归并
        merge(arr, l, mid, mid+1, r);
    }

    void merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] < arr[j]){
                res.push_back(arr[i]);
                i++;
            }
            else{
                res.push_back(arr[j]);
                j++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }
    }
};

int main(){
    std::vector<int> input = {1, 3, 4, 2, 5};
    Solution S1;
    std::vector<int> res = S1.Merge_Sort(input);
    for(int num : res) std::cout << num << " ";
    return 0;
}

2--小和问题

        在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和,请编码实现求解一个数组的小和;

        实例,给定数组 [1, 3, 4, 2, 5],1 左边比 1 小的数,没有;3 左边比 3 小的数, 为 1;4 左边比 4 小的数, 为 1 和 3;2 左边比 2 小的数,为 1;5 左边比 5 小的数,为 1, 3, 4 和 2;因此数组的小数和为:1 + (1+3) + (1) + (1+3+4+2) = 16;

主要思路:

        在归并排序两两比较两个数组的元素时,就确定对应的小数和;具体做法是,分析当前数是另一个数组中多少个数的小数,即当前数多少次被用于计算小数和;

#include <iostream>
#include <vector>

class Solution{
public:
    int Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return 0;
        int sum = split(arr, 0, arr.size() - 1);
        return sum;
    }

    // 二分
    int split(std::vector<int> &arr, int l, int r){
        if(l == r) return 0;
        int mid = l + (r - l) / 2;
        int count1 = split(arr, l, mid);
        int count2 = split(arr, mid+1, r);
        int count3 = merge(arr, l, mid, mid+1, r);
        // 归并
        return count1 + count2 + count3;
    }

    int merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        int sum = 0;
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] < arr[j]){
                // 对于 arr[j, r2] 的数都会大于 arr[i],因此它们的小数和都包含arr[i]
                sum += (r2 - j + 1) * arr[i];
                res.push_back(arr[i]);
                i++;
            }
            else{
                res.push_back(arr[j]);
                j++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }

        return sum;
    }
};

int main(){
    std::vector<int> input = {1, 3, 4, 2, 5};
    Solution S1;
    int res = S1.Merge_Sort(input);
    std::cout << res << " " << std::endl;
    return 0;
}

3--逆序对问题

主要思路:

        在归并排序两两比较两个数组的元素时,就确定对应的逆序对;具体做法是,分析当前数(arr2)在另一个数组(arr1)中有多少个逆序数

#include <iostream>
#include <vector>

class Solution{
public:
    int Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return 0;
        int sum = split(arr, 0, arr.size() - 1);
        return sum;
    }

    // 二分
    int split(std::vector<int> &arr, int l, int r){
        if(l == r) return 0;
        int mid = l + (r - l) / 2;
        int count1 = split(arr, l, mid);
        int count2 = split(arr, mid+1, r);
        int count3 = merge(arr, l, mid, mid+1, r);
        // 归并
        return count1 + count2 + count3;
    }

    int merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        int sum = 0;
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] > arr[j]){
                // 对于 arr[j, r2] 的数都会大于 arr[i],因此它们的小数和都包含arr[i]
                sum += (r1 - i + 1);
                res.push_back(arr[j]);
                j++;
            }
            else{
                res.push_back(arr[i]);
                i++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }

        return sum;
    }
};

int main(){
    std::vector<int> input = {7, 5, 6, 4};
    Solution S1;
    int res = S1.Merge_Sort(input);
    std::cout << res << " " << std::endl;
    return 0;
}

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

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

相关文章

手工测试VS自动化测试到底那个更胜一筹?

手工与自动化只是一种形式&#xff0c;真正的核心是测试用例、业务模型和测试分析。当企业的产品规模开始膨胀的时候&#xff0c;尤其是产品迭代加快是不是能及时得到测试验证支持是很重要的。这些靠手工测试是基本无法实现的&#xff0c;手工测试会严重的拖慢产品进度&#xf…

快速排序和qsort函数详解详解qsort函数

&#x1f495;是非成败转头空&#xff0c;青山依旧在&#xff0c;几度夕阳红&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;快速排序和qsort函数详解 前言&#xff1a; 我们之前学习过冒泡排序&#xff0c;冒泡排序尽管很方便&#xff0c;但也存在一些局限性…

类图的6种关系和golang应用

文章目录 1. 依赖和关联1.1 依赖&#xff08;Dependency&#xff09;概念类图示例代码示例 1.2 关联&#xff08;Association&#xff09;概念类图示例代码示例 2. 组合和聚合&#xff08;特殊的关联关系&#xff09;2.1 聚合&#xff08;Aggregation&#xff09;概念类图示例代…

nginx编译以及通过自定义生成证书配置https

1. 环境准备 1.1 软件安装 nginx安装编译安装以及配置https&#xff0c;需要gcc-c pcre-devel openssl openssl-devel软件。因此需要先安装相关软件。 yum -y install gcc-c pcre-devel openssl openssl-devel wgetopenssl/openssl-devel&#xff1a;主要用于nginx编译的htt…

Unity限制在一个范围内移动

Unity限制在一个范围内移动 这个例子中&#xff0c;我们学习Vector3.ClampMagnitude的用法&#xff0c;限制小球在范围内移动。 在地图上放了一个小球&#xff0c;让他移动&#xff0c;但是不想让他掉下去&#xff0c;限制在一个球星范围内&#xff0c;就好像绳子拴住了一样&…

MySQL流程控制(二十八)

二八佳人体似酥&#xff0c;腰悬利剑斩愚夫&#xff0c;虽然不见人头落,暗里教君骨髓枯。 上一章简单介绍了MySQL变量(二十七) ,如果没有看过,请观看上一章 一. 定义条件与处理程序 定义条件是事先定义程序执行过程中可能遇到的问题&#xff0c;处理程序定义了在遇到问题时应…

跨境B2B2C多用户购物网站源码快速部署

​ 搭建跨境B2B2C多用户购物网站需要以下步骤&#xff1a; 1. 确定业务模式和定位&#xff1a;确定网站的业务模式&#xff0c;包括跨境B2B2C的商业模式以及目标用户定位。 2. 营业执照和域名注册&#xff1a;根据当地法律要求&#xff0c;注册一家具有法人资格的公司&#xff…

java Springboot02--Controller,文件上传,拦截器

因为前后端分离了&#xff0c;所以这个项目基本用不到controller 这句话意思&#xff1a; controller只能用get接受前端的请求 RequestMapping(value "/hello",method RequestMethod.GET) GetMapping("/hello") 这两句等价的 前段传递参数&#xff0…

炸裂,靠“吹牛”过京东一面,月薪40K

说在前面 在40岁老架构师尼恩的&#xff08;50&#xff09;读者社区中&#xff0c;经常有小伙伴&#xff0c;需要面试美团、京东、阿里、 百度、头条等大厂。 下面是一个5年小伙伴成功拿到通过了京东一面面试&#xff0c;并且最终拿到offer&#xff0c;月薪40K。 现在把面试…

搜索综合训练

搜索综合训练 选数详细注释的代码 小木棍详细注释的代码 费解的开关详细注释的代码 选数 详细注释的代码 #include <iostream> #include <vector>using namespace std;// 判断一个数是否为素数 bool isPrime(int num) {if (num < 1)return false;// 判断从2到s…

利用状态监测和机器学习提高冷却塔性能的具体方法

在现代工业生产中&#xff0c;冷却塔扮演着至关重要的角色&#xff0c;它们的性能直接影响着工艺流程的稳定性和效率。为了确保冷却塔的正常运行和减少系统故障&#xff0c;状态监测和机器学习成为了关键技术。 图.冷却塔&#xff08;PreMaint&#xff09; 在前文《基于人工智…

P1629 邮递员送信(最短路)(内附封面)

邮递员送信 题目描述 有一个邮递员要送东西&#xff0c;邮局在节点 1 1 1。他总共要送 n − 1 n-1 n−1 样东西&#xff0c;其目的地分别是节点 2 2 2 到节点 n n n。由于这个城市的交通比较繁忙&#xff0c;因此所有的道路都是单行的&#xff0c;共有 m m m 条道路。这…

02_kafka_基本概念_基础架构

文章目录 常见的消息队列工作模式基本概念kafka 特性Kafka 基本架构topic 分区的 目的/ 好处 日志存储形式消费者&#xff0c;消费方式 逻辑消费组 高性能写入&#xff1a; 顺序写 mmap读取&#xff1a;零拷贝DMA 使用场景 常见的消息队列工作模式 至多一次&#xff1a;消息被…

cnvd通用型证书获取姿势

因为技术有限&#xff0c;只能挖挖不用脑子的漏洞&#xff0c;平时工作摸鱼的时候通过谷歌引擎引擎搜索找找有没有大点的公司有sql注入漏洞&#xff0c;找的方法就很简单&#xff0c;网站结尾加上’&#xff0c;有异常就测试看看&#xff0c;没有马上下一家&#xff0c;效率至上…

基于Python++PyQt5马尔科夫模型的智能AI即兴作曲—深度学习算法应用(含全部工程源码+测试数据)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PC环境配置 模块实现1. 钢琴伴奏制作1&#xff09;和弦的实现2&#xff09;和弦级数转为当前调式音阶3&#xff09;根据预置节奏生成伴奏 2. 乐句生成1&#xff09;添加音符2&#xff09;旋律生成3&#xff09;节…

Llama2 评测大公开!知识库场景下能否赶超 ChatGPT?

AIGC 人狂喜&#xff01;最近&#xff0c;Meta AI 发布了大语言模型 Llama2&#xff0c;为大模型的开发者注入了一剂强心针&#xff0c;因为无论从其灵活性、竞争力还是便捷性来看&#xff0c;都有不小的优势。 具体来看&#xff1a; Llama2 为开源产品且可免费商用&#xff0c…

【Spring AOP】什么是AOP

文章目录 1、AOP思想2、AOP入门案例3、AOP工作流程4、AOP切入点表达式5、AOP的五种通知类型6、AOP通知获取数据7、案例&#xff1a;百度网盘密码数据兼容处理8、AOP总结 1、AOP思想 AOP&#xff0c;即Aspect Oriented Programming&#xff0c;面向切面编程。是一种编程范式&am…

8.18信号量Semaphore和CountDownLatch

一 .Semaphore: 1.Semaphore是一个计数器(变量),描述可用资源的个数,用来判断是否有临界资源可用. 2.临界资源:多个进程或线程并发执行的实体可以公共使用到的资源. 3.pv操作:p操作(accquire(申请))表示计数器减一,v操作(release(释放))表示计数器加一. 4.锁是特殊的信号量…

RISC-V公测平台发布:如何在SG2042上玩转OpenMPI

About HS-2 HS-2 RISC-V通用主板是澎峰科技与合作伙伴共同研发的一款专为开发者设计的标准mATX主板&#xff0c;它预装了澎峰科技为RISC-V高性能服务器定制开发的软件包&#xff0c;包括各种标准bencmark、支持V扩展的GCC编译器、计算库、中间件以及多种典型服务器应用程序。…

[webpack] 处理样式 (二)

文章目录 1.介绍2.处理 Css 资源2.1 导入包2.2 功能配置2.3 添加 Css 资源 3.处理 Less 资源3.1 导入包3.2 功能配置3.3 添加 Less 资源 4.处理 Sass 和 Scss 资源4.1 导入包4.2 配置4.3 添加 Sass 资源4.4 运行webpack 5.处理 Styl 资源5.1 导入包5.2 配置5.3 添加 Styl 资源5…