【左程云算法全讲11】贪心算法 并查集

系列综述:
💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!
🌈【C++】秋招&实习面经汇总篇


文章目录

      • 贪心算法
      • 并查集
    • 参考博客


😊点此到文末惊喜↩︎

贪心算法

  1. 需要整理堆的使用,重写cmp
auto cmp = [&](const int& a, const int &b) {
    return cnt[a] < cnt[b];//此处cnt可由上文完成定义(最大堆--跟sort正好相反)
};
priority_queue<int, vector<int>, decltype(cmp)>pq{cmp};
  1. 分解过程
    • 分解业务
    • 根据业务逻辑找到不同的贪心策略
    • 可以举出反例的贪心策略直接跳过,不能举出反例的要证明其有效性
  2. 贪心算法的解题套路
    • 实现一个不依靠贪心策略的解法X,可以用最暴力的尝试
    • 脑补出贪心策略A、贪心策略B、贪心策略C…
    • 用解法X和对数器,用实验的方式得知哪个贪心策略正确
    • 不要去纠结贪心策略的证明
  3. 贪心策略:通常使用堆和排序
  4. 示例:排序式贪心
    • 题目:
      • 一些项目要占用一一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。
      • 给你每- -个项目开始的时间和结束的时间
      • 你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。
      • 返回最多的宣讲场次。
    • 贪心思路:每次优先安排结束时间最早的,并且将无法安排的进行删除
  5. 示例:堆式贪心1
    • 题目:
      • 一块金条切成两部分,需要花费和原长度一样的铜板数量
      • 比如长度为20的金条,不管怎么切,都要花费20个铜板。
      • 一群人各自分到自己想要的金条部分(和为总长度),怎么分最省铜板?
    • 思路1:每次尽可能的切下最大的部分
    • 思路2:使用哈夫曼树,每次弹出最小的两个数合并后在压入
      在这里插入图片描述
  6. 示例:堆式贪心2
    • 题目:
      • 输入:正数数组costs、正数数组profits、 正数K、正数M。costs[]表示i号项目的花费,profits[]表示i号项目在扣除花费之后还能挣到的钱(利润)
      • K表示你只能串行的最多做k个项目,M表示你初始的资金
      • 说明:每做完一个项目,马上获得的收益,可以支持你去做下一个项目。不能并行的做项目。
      • 输出:你最后获得的最大钱数。
    • 思路1:建立两个堆,一个以costs作为key的小根堆,一个是以profits作为key的大根堆。
    struct Program {
    	int p;
    	int c
    	Program(int profit, int cost) : p(profit), c(cost){}
    }
    
    int FindMaxProfits(vector<int> profits, vector<int> costs, int times, int surplus) {
    	// 比较最小花费
    	auto cmp_min_cost = [](const Program &a, const Program &b)->bool{
    		return a.c < b.c;
    	};
    	// 比较最大利润
    	auto cmp_max_profit = [](const Program &a, const Program &b)->bool{
    		return a.p > b.p;
    	};
    	// 关于花费的小根堆
    	priority_queue<Program , vector<Program>, decltype(cmp_min_cost)> min_cost_pq;
    	// 关于利润的大根堆
    	priority_queue<Program , vector<Program>, decltype(cmp_max_profit)> max_profit_pq;
    	// 将所有花费压入优先队列中
    	for (int i = 0; i < profits.size(); ++i) {
    		Program pg = {profits[i], costs[i]};
    		min_cost_pq.push(pg);
    	}	
    	// 每次循环取出所有可支持的项目,并压入最大利润队列
    	for (int i = 0; i < times; ++i) {
    		while (!min_cost_pq.empty() && min_cost_pq.top().c <= surplus){
    			Program pg = min_cost_pq.top();
    			min_cost_pq.pop();
    			max_profit_pq.push(pg);
    		}
    		// 如果最大利润队列为空,说明没有符合的项目可以继续进行
    		if (max_profit_pq.empty()) {
    			return surplus;
    		}
    		// 获取最大利润
    		surplus += max_profit_pq.top().p;
    		max_profit_pq.pop();
    	}	
    
    }
    

并查集

  1. 基本操作
    • 并:合并两个子集为一个新的集合
    • 查:通过查找一个结点的根节点,从而查找元素所属子集
  2. 作用:快速确定集合中的两两元素是否属于S的同一子集
  3. 基本并查集
    • 问题:每一次Find操作的时间复杂度为O(H),H为树的高度,由于树的不断合并可能会使树严重不平衡,最坏情况每个节点都只有一个子节点,如下图3(第一个点为根节点)在这里插入图片描述
    #include <vector>
    class DisjSet {
    private:
    	vector<int> parent; 
    public:
    	DisjSet(int max_size) : parent(vector<int>(max_size)) {
    		// 各自为营:初始化每一个元素的根节点都为自身
    		for(int i = 0; i < max_size; i++) 
    			parent[i] = i; 
    	}
    	// 查找:没找到就一直递归查看父亲结点
    	int find(int x) {
    		return (parent[i] == x ? x : find(parent[i]);
    	}
    	// 合并:将 x1 所在的集合的根节点的父节点设置为 x2 所在集合的根节点
    	void to_union(int x1, int x2) {
            parent[find(x1)] = find(x2);
        }
    	// 判断两个元素是否属于同一个集合
        bool is_same(int e1, int e2) {
            return find(e1) == find(e2);
        }
    };
    
    
  4. 优化并查集
    • 路径压缩:查询过程中,将沿途每个结点的父结点都设置为根结点,下次就可以减少查询路径长度
    • 按秩合并:“按秩合并”。实际上就是在合并两棵树时,将高度较小的树合并到高度较大的树上。这里我们使用“秩”(rank)代替高度,秩表示高度的上界,通常情况我们令只有一个节点的树的秩为0,严格来说,rank + 1才是高度的上界;两棵秩分别为r1、r2的树合并,如果秩不相等,我们将秩小的树合并到秩大的树上,这样就能保证新树秩不大于原来的任意一棵树。如果r1与r2相等,两棵树任意合并,并令新树的秩为r1 + 1。
    #include <vector>
    class DisjSet {
      private:
        std::vector<int> parent;
        std::vector<int> rank; // 秩
      public:
        DisjSet(int max_size) : parent(std::vector<int>(max_size)),
                                rank(std::vector<int>(max_size, 0)) {
            for (int i = 0; i < max_size; ++i)
                parent[i] = i;
        }
        int find(int x) {
            return x == parent[x] ? x : (parent[x] = find(parent[x]));
        }
        void to_union(int x1, int x2) {
            int f1 = find(x1);
            int f2 = find(x2);
            if (rank[f1] > rank[f2])
                parent[f2] = f1;
            else {
                parent[f1] = f2;
                if (rank[f1] == rank[f2])
                    ++rank[f2];
            }
        }
        bool is_same(int e1, int e2) {
            return find(e1) == find(e2);
        }
    };
    


少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
不如点赞·收藏·关注一波

🚩点此跳转到首行↩︎

参考博客

  1. 知乎并查集
  2. 待定引用
  3. 待定引用
  4. 待定引用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Maven编译报错:javacTask: 源发行版 1.8 需要目标发行版 1.8

报错截图&#xff1a; IDEA中的jdk检查都正常设置的1.8一点毛病没有。参考其他帖子链接如下&#xff1a; https://blog.csdn.net/zhishidi/article/details/131480199https://blog.51cto.com/u_16213460/7197764https://blog.csdn.net/lck_csdn/article/details/125387878 逐…

Android 13.0 recovery出厂时清理中字体大小的修改

1.前言 在13.0的系统rom定制化开发中,在recovery模块也是系统中比较重要的模块,比如恢复出厂设置,recovery ota升级, 清理缓存等等,在一些1080p的设备,但是density只是240这样的设备,会在恢复出厂设置的时候,显示的字体有点小, 产品要求需要将正在清理的字体调大点,这…

A Comprehensive Survey on Graph Neural Networks

A Comprehensive Survey on Graph Neural Networks----《图神经网络研究综述》 摘要 近年来&#xff0c;深度学习已经彻底改变了许多机器学习任务&#xff0c;从图像分类和视频处理到语音识别和自然语言理解。这些任务中的数据通常在欧几里得空间中表示。然而&#xff0c;越来…

个体诊所电子处方模板,佳易王药店电子处方系统门诊病历软件教程

个体诊所电子处方模板&#xff0c;佳易王药店电子处方系统门诊病历软件教程 软件支持中医&#xff0c;西医&#xff0c;对于经常使用的配方&#xff0c;可以自己设置配方模板&#xff0c;点击右侧 配方模板&#xff0c;选择后一键导入配方即可。处方单使用A5纸打印。软件可以试…

【OpenCV实现图像:OpenCV进行OCR字符分割】

文章目录 概要基本概念读入图像图像二值化小结 概要 在处理OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;时&#xff0c;利用传统的图像处理方法进行字符切分仍然是一种有效的途径。即便当前计算机视觉领域主导的是卷积神经网络&#xf…

【软考篇】中级软件设计师 第四部分(三)

中级软件设计师 第四部分&#xff08;三&#xff09; 三十四. 结构化开发方法34.1 内聚34.2 耦合 三十五. 测试基础知识三十六. 面向对象36.1 UML图36.2 设计模式36.3 数据流图 读前须知&#xff1a; 【软考篇】中级软件设计师 学前须知 上一章节&#xff1a; 【软考篇】中级软…

【入门篇】1.7 Redis 之 codis 入门介绍

文章目录 1. 简介2. Codis的安装与配置下载编译源码安装1. 安装 Go 运行环境2. 设置编译环境3. 下载 Codis 源代码4. 编译 Codis 源代码 Docker 部署 3. Codis的架构Codis的架构图和组件Codis的工作流程 4. Codis的核心特性自动数据分片数据迁移高可用性全面支持Redis命令分布式…

Client not connected, current status:STARTING

上面的问题出现在springboot整合nacos的时候出现的 首先说明一点&#xff0c;我出现这个问题是使用了nacos集群&#xff0c;nacos版本为2.2.3&#xff0c;且使用了nginx做了负载均衡&#xff0c;如果您和我一样&#xff0c;那么可以接着往下看。 1️⃣&#xff1a;当nacos版本为…

windows与wsl互传文件

1.把windows上的文件传到wsl中&#xff0c;\\wsl.localhost\Ubuntu-22.04\mnt\wsl 将你要传的文件放到wsl这个路径下&#xff0c;Ubuntu-22.04是我的子系统&#xff0c;换成自己对应的 2.把wsl中的文件传到windows中 将wsl中的文件放到 /mnt/c 或 /mnt/d 中&#xff0c;这两…

汇川伺服【选型目录】

sv680旗舰&#xff1a; 编码器位数&#xff1a;26bit 电机额定转速&#xff1a;3000r【3k】圈脉冲&#xff1a; sv670标准&#xff1a; 编码器位数&#xff1a;23bit【台达B3:23bit&#xff0c;台达A2&#xff1a;bit】 电机额定转速&#xff1a;3000r【3k】圈脉冲&#xff1…

【AI视野·今日Sound 声学论文速览 第三十五期】Fri, 27 Oct 2023

AI视野今日CS.Sound 声学论文速览 Fri, 27 Oct 2023 Totally 8 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Controllable Generation of Artificial Speaker Embeddings through Discovery of Principal Directions Authors Florian Lux, Pascal T…

chatGPT API中参数temperature的含义是什么

在 ChatGPT API 中&#xff0c;temperature 参数用于控制回答的确定性和创造性。temperature 的值范围通常是从 0 到 1。这个参数影响模型生成回答时的随机性&#xff1a; 低温度值&#xff08;如 0 或接近 0&#xff09;&#xff1a;会导致模型生成更确定、更一致、更少出乎意…

微服务实战系列之Sentinel

前言 微服务架构&#xff08;Microservice Architecture&#xff09;是一种架构概念&#xff0c;旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。 近年来&#xff0c;微服务已赫然崛起于IT界&#xff0c;越来越多的程序员不得不向之靠拢。也正因为各行各业都愿为…

ZOC8 for Mac:最佳终端仿真器,助力您的工作效率飞升!

在现代的工作环境中&#xff0c;终端仿真器扮演着不可或缺的角色。无论是开发人员、系统管理员还是网络工程师&#xff0c;都需要一个功能强大、易于使用的终端仿真器来处理各种任务。而ZOC8 for Mac正是为这些专业人士而打造的最佳选择。 作为一款全功能的终端仿真软件&#…

Apache SCXML2 RCE漏洞

文章目录 前言源码利用上传恶意xml文件构造payload搭建Apache服务器 远程RCE 前言 在做 [HDCTF 2023]BabyJxVx 遇到的知识点&#xff0c;但是没公网的服务器只能作罢&#xff0c;写下这篇文章记录 源码利用 public String Flag(RequestParam(required true) String filenam…

微信如何设置自动保存图片和视频

8-6 在日常的工作中&#xff0c;如果你需要经常或者每天都要对同事们发来的大量图片和视频进行保存的&#xff0c;这种工作需要花费很多时间&#xff0c;如果你想节省这些手工时间的话&#xff0c;也许本文适合你&#xff0c;首先要明白的是&#xff0c;微信本身是没有任何相关…

备战旺季,赛盈分销解析2023年美国人爱买的年终爆款!

今年10月份美国人增加了自己在线上渠道的支出&#xff0c;Adobe Analytics的调查报告显示&#xff0c;美国消费者当月的线上支出达到了768亿美元&#xff0c;同比增长5.9%。 数据还表明&#xff0c;1-10月份美国人的线上购物相比去年增长了4.3%&#xff0c;整体消费达到7590亿…

二十、泛型(9)

本章概要 对缺乏潜在类型机制的补偿 反射将一个方法应用于序列 Java 8 中的辅助潜在类型 使用 Suppliers 类的通用方法 总结&#xff1a;类型转换真的如此之糟吗&#xff1f; 对缺乏潜在类型机制的补偿 尽管 Java 不直接支持潜在类型机制&#xff0c;但是这并不意味着泛型代…

笔记53:torch.nn.rnn() 函数详解

参数解释&#xff1a; &#xff08;1&#xff09;input_size()&#xff1a;即输入信息 Xt 的每个序列的独热编码向量的长度&#xff0c;即 len(vocab) &#xff08;2&#xff09;hidden_size()&#xff1a;即隐变量 h 的维度&#xff08;维度是多少&#xff0c;就代表用几个数…

北京君正客户应用案例:掌静脉3D人脸猫眼视屏智能锁

凯迪仕在今年4月发布了智能锁旗舰新品K70 Pro Max掌静脉3D人脸猫眼视屏智能锁&#xff0c;随即这款新品也成了行业热议的焦点。凯迪仕每次新品都力求突破精益求精&#xff0c;不仅追求科技感、高级感与品质感&#xff0c;而且赋予科技温度&#xff0c;带来人文化的关怀。K70 Pr…