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

【左程云算法全讲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 cProgram(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);}
    };
    
  5. 并查集示例
    • 题目
      • 如果两个user,a字段一样,或者b字段一样、或者c字段一样,就认为是同一个人
      • 请合并user,并返回合并后的人数
struct User {string a;string b;string c;User(string a1, string b1, string c1) : a(a1), b(b1), c(c1){} 
};


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

🚩点此跳转到首行↩︎

参考博客

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

相关文章:

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

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于左程云算法课程进行的&#xff0c;每个知识点的修正和深入主要参考…...

CSS中4种关系选择器

元素(标签)之间的关系 父元素&#xff1a;直接包含子元素的元素 子元素&#xff1a;直接被父元素包含的元素 祖先元素&#xff1a;直接或间接包含后代元素的元素&#xff0c;父元素也是祖先元素 后代元素&#xff1a;直接或间接被祖先元素包含的元素&#xff0c;子元素也是后代…...

蓝牙模块(HC-05)与手机连接,蓝牙与蓝牙互联,电脑通过蓝牙控制单片机

任务一&#xff1a;蓝牙与手机连接 所用模块&#xff1a; HC-05蓝牙模块&#xff0c;USB TO TTL手机APP为SPP蓝牙串口 第一章&#xff1a;蓝牙模块配置 一&#xff1a;HC-05与USB TO TTL连接 EN&#xff1a;为使能引脚&#xff0c;一般不接 VCC&#xff1a;接USB TO TTL模…...

安装 eslint 配置指南 及 遇到的一些问题记录

前端eslint配置指南 背景 当前前端项目风格混乱&#xff0c;每个人有自己的开发习惯&#xff0c;有自己的格式化习惯&#xff0c;不便于项目的风格统一&#xff0c;不利于代码维护有的项目eslint没有用起来&#xff0c;没有起到规范代码的作用&#xff0c;导致出现一些基础代码…...

trzsz支持文件拖动到终端进行上传,类似lrzsz

考虑到 LapTop -> Host 1 -> Host 2 -> Docker -> TMUX&#xff0c;使用scp或sftp命令不方便&#xff1b;使用rz和sz命令就会方便很多&#xff0c;但是却又与 TMUX 不兼容&#xff08;备注&#xff1a;Tmux是一个终端复用工具&#xff0c;允许用户在一个终端窗口中…...

Doris DDL和DML

1 创建用户和数据库 1)创建test用户 mysql -h hadoop1 -P 9030 -uroot -p create user test identified by test; 2)创建数据库 create database test_db; 3)用户授权...

NewStarCTF2023 Reverse方向Week3 ez_chal WP

分析 题目&#xff1a;ez_chal 一个XTEA加密&#xff0c; V6是key&#xff0c;v5是输入&#xff0c;然后v7就是密文。 看了v6&#xff0c;要用动调。 ELF文件用ida的远程调试。 然后在kali上输入长度为32的flag 全部转换成dd 再提取密文。 EXP #include <stdio.h>…...

程序员如何“升级打怪”?我用了这几个“歪瓜”!

不会吧&#xff1f;不会吧&#xff1f;计算机本命专业出身、以及半路出家的&#xff0c;混了几年了&#xff0c;还在新手村&#xff1f;对得起这几年摸的鱼&#xff1f; 思考一下&#xff1a;如何从小白一跃为大师&#xff0c;从此走上人生巅峰、迎娶白富美&#xff1f;变强只…...

模具制造厂ERP都有哪些牌子?模具制造厂ERP有什么用

模具制造通常会涉及物料领用、成品入库、工艺流转、投入水口、配方、模具、生产啤数统计等众多环节&#xff0c;各个环节数据的实时和准确传递&#xff0c;有利于企业清晰掌握订单生产进度&#xff0c;及时调整制造策略等。 有些模具制造工厂采用传统的管理模式&#xff0c;随…...

FPGA语法相关知识合集

一.相关概念 1.四种结构说明语句 2.initial 与 always 的异同点 3.task 与 function 的3个不同点 4.task的语法结构(定义及调用) 5.function的语法结构(定义及调用) 6.function 的一个必须有和一个必须没有&#xff0c;使用规则 7.自动&#xff08;递归&#xff09;函数…...

2023年Java核心技术大会(Core Java Week 2023)-核心PPT资料下载

一、峰会简介 人工智能在22年、23年的再次爆发让Python成为编程语言里最大的赢家&#xff1b;云原生的持续普及令Go、Rust等新生的语言有了进一步叫板传统技术体系的资本与底气。我们必须承认在近几年里&#xff0c;Java阵营的确受到了前所未有的挑战&#xff0c;出现了更多更…...

Vue3 源码解读系列(十五)——编译

编译 web 模式的编译主要做了 3 件事&#xff1a; 解析 template 生成 ASTAST 转换生成代码 /*** web 编译* param {string} template - 待编译的模板字符串* param {string} options - 配置对象*/ function compile(template, options {}) {return baseCompile(template, …...

gitlab安装配置及应用

安装 ##安装依赖 yum install -y curl policycoreutils-python openssh-server perl#上传包 rz gitlab-jh-16.5.2-jh.0.el7.x86_64.rpm 安装 yum install gitlab-jh-16.0.3-jh.0.el7.x86_64.rpm 初始化并启动 # 以下两种方法都可以配置访问地址&#xff0c;第一种需要在yum安…...

Docker Volume: 实现容器间数据共享与持久化的利器

文章目录 Docker Volume的作用Docker Volume与容器内数据的比较优势劣势 Docker Volume的创建和管理创建Docker Volume管理Docker Volume 演示Docker Volume的挂载Docker Volume的生命周期安全性考虑与Docker Volume应用场景Docker Volume与多容器协作容器迁移与Docker Volume未…...

redis问题归纳

1.redis为什么这么快&#xff1f; &#xff08;1&#xff09;基于内存操作&#xff1a;redis的所有数据都存在内存中&#xff0c;因此所有的运算都是内存级别的&#xff0c;所以性能比较高 &#xff08;2&#xff09;数据结构简单&#xff1a;redis的数据结构是专门设计的&…...

改进YOLOv8:结合ConvNeXt V2骨干网络!使用MAE共同设计和扩展ConvNet

🗝️YOLOv8实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv8:我的专业笔记与技术总结   -- YOLOv8轻松上手, 适用技术小白,文章代码齐全,仅需 …...

基于SpringBoot+Vue的新能源汽车充电桩管理系统

基于SpringBootVue的新能源汽车充电桩管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 充电桩详情 管理员界面 摘要 本项目是基于Spring Boot 和 …...

Linux进程通信——消息队列

概念 消息队列&#xff0c;是消息的链接表&#xff0c;存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。 特点 1.消息队列是面向记录的&#xff0c;其中的消息具有特定的格式以及特定的优先级。&#xff08;消息队列是结构体&#xff09; 2.消息队列独立于发送与接…...

ArcGIS教程——ArcGIS工具-按线分割面

功能说明 在ArcGIS数据处理过程中&#xff0c;有时需要沿线把面要素分割开&#xff0c;可以使用高级编辑中的分割面&#xff08;Cut Polygon&#xff09;工具。那么&#xff0c;如果要用线图层分割面图层该怎么办呢&#xff1f;地理遥感生态网平台开发了一个自定义模型工具。它…...

C语言进阶之冒泡排序

✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 前情回顾 1、回调函数 2、冒泡排序 3、库函数qsort cmp&#xff08;sqort中的比较函数&#xff0c;需要我们自定义&#xff09; …...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

【技巧】dify前端源代码修改第一弹-增加tab页

回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码&#xff0c;在知识库增加一个tab页"HELLO WORLD"&#xff0c;完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...