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

贪心算法(2024/7/16)

1合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

思路:本题是判断重叠区间问题  先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以.

  1. 排序: 首先,根据每个区间的左边界,对给定的区间集合 intervals 进行升序排序。这是为了确保处理区间时,可以按顺序考虑它们的位置关系。

  2. 合并过程: 排序完成后,使用一个结果集合 result 来存储最终合并后的区间。开始时,将排序后的第一个区间直接放入 result 中。

  3. 遍历区间: 从第二个区间开始遍历,与 result 中的最后一个区间比较:

    • 如果当前区间与 result 中的最后一个区间有重叠(即当前区间的左边界小于等于 result 中最后一个区间的右边界),则更新 result 中最后一个区间的右边界为两者的最大值,以实现合并。
    • 如果当前区间与 result 中的最后一个区间没有重叠,则直接将当前区间加入 result

代码

class Solution {
public:// 定义一个静态函数作为比较函数,用于排序static bool cmp(const vector<int>& a, const vector<int>& b) {return a[0] < b[0]; // 按照区间的左边界进行升序排序}vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> result;if (intervals.empty()) return result; // 如果区间集合为空直接返回空结果// 使用cmp函数对区间进行排序sort(intervals.begin(), intervals.end(), cmp);// 第一个区间直接放入结果集合中result.push_back(intervals[0]); for (int i = 1; i < intervals.size(); i++) {if (result.back()[1] >= intervals[i][0]) { // 发现重叠区间// 合并区间,只需要更新结果集合中最后一个区间的右边界result.back()[1] = max(result.back()[1], intervals[i][1]); } else {result.push_back(intervals[i]); // 区间不重叠,将当前区间加入结果集合}}return result;}
};

2 单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

提示:

  • 0 <= n <= 109

思路:

举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。

那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299

  1. 将整数 N 转换为字符串 strNum,便于按位处理。
  2. 从右向左遍历字符串 strNum,找到第一个出现递减的位置 i,即满足 strNum[i-1] > strNum[i]
  3. 将第 i-1 位减一,并标记 flag 为 i,表示从这里开始需要调整。
  4. 将从 flag 开始的所有位置的字符设为 ‘9’,以确保得到最大的单调递增数。
  5. 将处理后的字符串转换为整数并返回作为结果。

代码:

class Solution {
public:int monotoneIncreasingDigits(int N) {string strNum = to_string(N);// flag用来标记需要修改的位置,初始化为字符串长度,防止第二个循环在未赋值的情况下执行int flag = strNum.size();// 从倒数第二位开始向前遍历for (int i = strNum.size() - 1; i > 0; i--) {// 如果当前位大于前一位,则前一位需要减一,并更新flagif (strNum[i - 1] > strNum[i]) {flag = i; // 记录需要减一的位置strNum[i - 1]--; // 前一位减一}}// 将flag位置及之后的所有位数变为9,以获得最大的单调递增数for (int i = flag; i < strNum.size(); i++) {strNum[i] = '9';}return stoi(strNum); // 转换为整数并返回}
};

3监控二叉树

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

示例 1:

输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。

示例 2:

输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。


提示:

  1. 给定树的节点数的范围是 [1, 1000]
  2. 每个节点的值都是 0。

思路:我们要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!可以使用后序遍历也就是左右中的顺序,这样就可以在回溯的过程中从下到上进行推导了.

给定一个二叉树,节点状态有三种:未被覆盖、已被覆盖(无需额外摄像头)、已安装摄像头。目标是找出最少需要安装的摄像头数量,覆盖整棵树的所有节点。

定义递归函数 traversal,对当前节点进行处理:

  • 如果左右子树有任意一个是未被覆盖的状态(返回2),则当前节点需要安装摄像头,返回1表示当前节点已安装摄像头。
  • 如果左右子树都已被覆盖(返回0),则当前节点不需要额外的摄像头覆盖。
  • 如果左右子树有一个已安装摄像头(返回1),则当前节点被覆盖,返回0。
  1. 根节点处理: 调用 traversal 函数处理根节点。如果根节点未被覆盖(返回2),则需要额外安装一个摄像头。

  2. 终返回 result,即安装摄像头的总数量。

代码: 

class Solution {
private:int result; // 记录需要安装摄像头的数量// 递归函数,返回当前节点的状态:// 0 - 节点已被覆盖// 1 - 节点安装了摄像头// 2 - 节点未被覆盖int traversal(TreeNode* cur) {if (cur == NULL) return 2; // 空节点默认已覆盖int left = traversal(cur->left);    // 处理左子树int right = traversal(cur->right);  // 处理右子树// 如果左右子树有任意一个未被覆盖,当前节点需要安装摄像头if (left == 2 || right == 2) {result++; // 安装摄像头return 1; // 当前节点已安装摄像头}// 如果左右子树的状态都是已覆盖,当前节点不需要额外摄像头覆盖else if (left == 0 && right == 0) {return 2; // 当前节点未被覆盖} else {return 0; // 当前节点已被覆盖}}public:int minCameraCover(TreeNode* root) {result = 0; // 初始化摄像头数量为0if (traversal(root) == 2) { // 如果根节点未被覆盖,则需额外安装摄像头result++;}return result; // 返回最终需要安装的摄像头数量}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 从0到1搭建数据中台(4):neo4j初识及安装使用
  • Golang 创建 Excel 文件
  • PlantUML-UML 绘图工具安装、Graphviz安装、本地使用/在线使用、语法、图示案例
  • 源码分析SpringCloud Gateway如何加载断言(predicates)与过滤器(filters)
  • Java毕业设计 基于SpringBoot的景区行李寄存管理系统
  • 【Django】网上蛋糕商城后台-类目管理
  • huawei USG6001v1学习---信息安全概念
  • 前端使用webSocket与后台建立连接并进行心跳监测机制
  • AWS基础知识
  • 专业PDF编辑工具:Acrobat Pro DC 2024.002.20933绿色版,提升你的工作效率!
  • WPF/C#:实现导航功能
  • 【go】Excelize处理excel表 带合并单元格、自动换行与固定列宽的文件导出
  • JCR一区级 | Matlab实现PSO-Transformer-LSTM多变量回归预测
  • PWM再理解(1)
  • 【Node.js】初识 Node.js
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 08.Android之View事件问题
  • Java,console输出实时的转向GUI textbox
  • 编写高质量JavaScript代码之并发
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 复杂数据处理
  • 计算机在识别图像时“看到”了什么?
  • 事件委托的小应用
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 国内开源镜像站点
  • 通过调用文摘列表API获取文摘
  • ​​​【收录 Hello 算法】9.4 小结
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #《AI中文版》V3 第 1 章 概述
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (02)vite环境变量配置
  • (2)STL算法之元素计数
  • (Ruby)Ubuntu12.04安装Rails环境
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (算法)N皇后问题
  • (一一四)第九章编程练习
  • . NET自动找可写目录
  • .Net OpenCVSharp生成灰度图和二值图
  • .net 按比例显示图片的缩略图
  • .net下简单快捷的数值高低位切换
  • .net中我喜欢的两种验证码
  • @ComponentScan比较
  • @JsonFormat与@DateTimeFormat注解的使用
  • []sim300 GPRS数据收发程序
  • [Android]一个简单使用Handler做Timer的例子
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [C++]C++基础知识概述
  • [C++基础]-初识模板
  • [Deep Learning] 神经网络基础
  • [HNOI2018]排列