代码随想录训练营 Day31打卡 贪心算法 part05 56. 合并区间 738. 单调递增的数字 968. 监控二叉树

代码随想录训练营 Day31打卡 贪心算法 part05

一、 力扣56. 合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。

按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴,所以是<=)

如图,(注意图中区间都是按照左边界排序之后了):

在这里插入图片描述
知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

代码实现

class Solution:def merge(self, intervals):result = []  # 用于存放合并后的区间结果if len(intervals) == 0:return result  # 如果区间集合为空,直接返回空的结果集intervals.sort(key=lambda x: x[0])  # 按照区间的左边界进行排序,这样可以保证后续区间的顺序性result.append(intervals[0])  # 将排序后的第一个区间直接加入结果集# 从第二个区间开始遍历for i in range(1, len(intervals)):# 如果当前区间的左边界小于或等于结果集中最后一个区间的右边界,说明区间重叠if result[-1][1] >= intervals[i][0]:# 合并区间:更新结果集中最后一个区间的右边界为当前区间和结果集中右边界的较大值result[-1][1] = max(result[-1][1], intervals[i][1])else:# 如果当前区间与结果集中最后一个区间不重叠,直接将当前区间加入结果集result.append(intervals[i])return result  # 返回合并后的区间结果集

力扣题目链接
题目文章讲解
题目视频讲解

二、 力扣738. 单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增
示例 1:
输入: n = 10
输出: 9
示例 2:
输入: n = 1234
输出: 1234

题目要求小于等于N的最大单调递增的整数,那么拿一个两位的数字来举例。

例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。

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

版本一

将输入整数 N 转换为字符串 strNum,方便逐位操作。
从右向左遍历字符串,检查每一位数字与前一位的关系。
如果发现当前位数字小于前一位,说明递增性被破坏,更新 flag 为当前的位置,并将前一位数字减1以修复递增性。
将从 flag 开始的所有位置上的数字改为9,确保生成的数字是最大且递增的。
最终,将修改后的字符串转换为整数返回。

class Solution:def monotoneIncreasingDigits(self, N: int) -> int:# 将整数N转换为字符串形式,方便逐位处理strNum = str(N)# flag用于标记从哪里开始将数字修改为9,初始值设置为字符串的长度,避免错误的更新flag = len(strNum)# 从右往左遍历字符串中的每一位for i in range(len(strNum) - 1, 0, -1):# 如果当前位的数字比前一位的数字小,说明递增性被破坏,需要调整if strNum[i - 1] > strNum[i]:flag = i  # 更新flag,记录需要修改的位置# 将前一位数字减1,并更新字符串strNum = strNum[:i - 1] + str(int(strNum[i - 1]) - 1) + strNum[i:]# 从flag位置开始,将其后的所有数字都变为9,以保证生成的数字最大且递增for i in range(flag, len(strNum)):strNum = strNum[:i] + '9' + strNum[i + 1:]# 最后将字符串转换回整数返回return int(strNum)

版本二

将输入整数 N 转换为字符列表 strNum,便于逐位修改。
如果当前位数字比前一位数字小,递增性被破坏。
将前一位数字减1,并将当前位置及其后面的数字全都设为9,保证最大化。
最后将字符列表转换为字符串,再转换为整数返回。

class Solution:def monotoneIncreasingDigits(self, N: int) -> int:# 将整数N转换为字符列表,便于逐位操作strNum = list(str(N))# 从右向左遍历字符串中的每一位for i in range(len(strNum) - 1, 0, -1):# 如果当前位数字比前一位数字小,说明递增性被破坏,需要调整if strNum[i - 1] > strNum[i]:# 将前一位数字减1strNum[i - 1] = str(int(strNum[i - 1]) - 1)# 将当前位置及其之后的所有数字都设为9,确保递增性并最大化for j in range(i, len(strNum)):strNum[j] = '9'# 将字符列表转换回字符串,再转换为整数返回return int(''.join(strNum))

版本三 贪心法 精简版

将整数 N 转换为字符串 strNum。
找到递增性被破坏的位置,如果找到,将前一位数字减1,后续所有位置设为9。
将字符串 strNum 转换为整数并返回。

class Solution:def monotoneIncreasingDigits(self, N: int) -> int:# 将整数N转换为字符串形式strNum = str(N)# 从右向左遍历字符串中的每一位for i in range(len(strNum) - 1, 0, -1):# 如果当前位数字比前一位数字小,递增性被破坏if strNum[i - 1] > strNum[i]:# 将前一位数字减1,并将当前位置及之后的所有数字设为9strNum = strNum[:i - 1] + str(int(strNum[i - 1]) - 1) + '9' * (len(strNum) - i)# 将最终的字符串转换为整数并返回return int(strNum)

力扣题目链接
题目文章讲解
题目视频讲解

三、 力扣968. 监控二叉树

给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视 其父对象、自身及其直接子对象
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
在这里插入图片描述
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2
在这里插入图片描述

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

本题我们要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!

如何隔两个节点放一个摄像头

来看看这个状态应该如何转移,先来看看每个节点可能有几种状态,我们分别有三个数字来表示:
0:该节点无覆盖
1:本节点有摄像头
2:本节点有覆盖

空节点的状态只能是有覆盖,这样就可以在叶子节点的父节点放摄像头了
主要有如下四类情况:

情况1:左右节点都有覆盖
左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。
在这里插入图片描述

情况2:左右节点至少有一个无覆盖的情况
这个不难理解,毕竟有一个孩子没有覆盖,父节点就应该放摄像头。
此时摄像头的数量要加一,并且return 1,代表中间节点放摄像头。

情况3:左右节点至少有一个有摄像头
如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)

情况4:头结点没有覆盖
以上都处理完了,递归结束之后,可能头结点 还有一个无覆盖的情况:
所以递归结束之后,还要判断根节点,如果没有覆盖,result++

代码实现

class Solution:# 贪心算法:从下往上安装摄像头,以确保安装数量最少,达到局部最优从而实现全局最优# 主要思路是跳过叶子节点,优先给叶子节点的父节点安装摄像头,并且每隔两层节点安装一个摄像头,直到根节点# 节点状态定义:# 0: 该节点未覆盖(需要安装摄像头)# 1: 该节点有摄像头# 2: 该节点已被覆盖(由子节点的摄像头覆盖)def minCameraCover(self, root: TreeNode) -> int:result = [0]  # 用于记录摄像头的安装数量,使用列表是为了在递归中修改该值# 调用递归函数,如果根节点未被覆盖,则需要在根节点安装一个摄像头if self.traversal(root, result) == 0:result[0] += 1return result[0]  # 返回最终安装的摄像头数量def traversal(self, cur: TreeNode, result: List[int]) -> int:if not cur:  # 如果当前节点为空,表示这个节点已被视为已覆盖(不需要安装摄像头)return 2# 递归处理当前节点的左子树left = self.traversal(cur.left, result)# 递归处理当前节点的右子树right = self.traversal(cur.right, result)# 情况1: 左右节点都有覆盖(但当前节点本身未被覆盖)# 如果左右子节点都处于已覆盖状态,但没有摄像头,当前节点需要摄像头来覆盖if left == 2 and right == 2:return 0  # 当前节点未被覆盖,返回0# 情况2: 当前节点的左右子节点至少有一个未被覆盖# 如果任意一个子节点未被覆盖,则当前节点需要安装摄像头elif left == 0 or right == 0:result[0] += 1  # 增加摄像头数量return 1  # 当前节点安装了摄像头,返回1# 情况3: 当前节点的子节点有一个摄像头覆盖,或者两个子节点都有摄像头覆盖# 在这种情况下,当前节点已经被覆盖,不需要额外安装摄像头else:return 2  # 当前节点已被覆盖,返回2

力扣题目链接
题目文章讲解
题目视频讲解

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

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

相关文章

【C++ 第十三章】AVL 二叉平衡树

1. AVL树的概念 普通二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。 因此&#xff0c;两位俄罗斯的数学家 G.M.Adelson-Velskii 和 E.M.Landis 在1962年发明…

【YashanDB知识库】共享集群YAC换IP

【标题】共享集群YAC换IP 【需求分类】安装部署&#xff0c;配置变更 【关键字】安装部署&#xff0c;更换IP&#xff0c;运维&#xff0c;配置变更&#xff0c;高可用&#xff0c;YAC 【需求描述】客户需要将已经部署的YAC集群更换IP&#xff0c;从测试网段切换生产网段 【…

高性能web服务器详解

一、Web服务的基础介绍 正常情况下单次web服务访问的流程简图&#xff1a; 1.1 Web服务介绍 这里介绍的是 Apache 和 NGINX 1.1.1 Apache 经典的Web服务端 Apache 起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发 目前经历了两大版本分别是 1.X 和 2.X…

高性能web服务器--nginx

下载nginx [rootnginx ~]# wget -c https://nginx.org/download/nginx-1.24.0.tar.gz [rootnginx ~]# tar zxf nginx-1.24.0.tar.gz创建nginx用户 [rootnginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx先安装依赖 dnf install gcc pcre-devel zlib-devel openssl-d…

p0级别事故 分类

信息化系统 P0至P4事故级别描述了不同严重程度的服务中断或功能故障&#xff0c;其中P0代表最高级别的事故。以下是各级别的详细描述&#xff1a; ● P0&#xff1a;核心业务重要功能不可用&#xff0c;且影响范围广泛&#xff0c;如大面积影响用户。这包括系统崩溃、页面无法访…

Android低内存设备系统优化

切记,所有的优化都遵循一条准则: 空间换时间,时间换空间。 一、前言 我们为什么会觉得卡顿、不流畅? 卡顿等性能问题的最主要根源都是因为渲染性能,Android系统很有可能无法及时完成那些复杂的界面渲染操作。Android系统每隔16ms发出信号,触发对UI进行渲染,如果每次渲染…

springboot整合mybatis以及mybatis-plus 开发

一、springboot整合mybatis 1.注解版 1.1 导入坐标 <dependencies><!--mybatis坐标--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</…

【C++】使用红黑树封装map与set

文章目录 1. 源码分析2. 调整红黑树的结构搭建map、set3. 红黑树的迭代器3.1 普通迭代器3.2 const迭代器3.3 map的operator[ ] 4. 完整代码4.1 RBTree4.2 MyMap4.3 MySet 对于map与set&#xff0c;它们一个是KV模型&#xff0c;一个是K模型&#xff0c;那我们要写两个红黑树吗&…

虚幻5|角色武器装备的数据库学习(不只是用来装备武器,甚至是角色切换也很可能用到)

虚幻5|在连招基础上&#xff0c;给角色添加武器并添加刀光|在攻击的时候添加武器并返回背后&#xff08;第一部分&#xff0c;下一部分讲刀光&#xff09;_unreal 如何给角色添加攻击-CSDN博客 目的&#xff1a;捡起各种不同的武器&#xff0c;捡起的武器跟装备的武器相匹配 …

【Hot100】LeetCode—234. 回文链表

目录 1- 思路快慢指针链表拆分反转链表 2- 实现⭐234. 回文链表——题解思路 3- ACM 实现 原题连接&#xff1a;234. 回文链表 1- 思路 快慢指针链表拆分反转链表 思路 ①将链表拆分前后两个部分——>找拆分点、②反转后面部分、③根据反转结果&#xff0c;同时利用两个指…

MySQL笔记01: MySQL入门_1.3 MySQL启动停止与登录

1.3 MySQL启动停止与登录 1.3.1 MySQL启动与停止 MySQL数据库分为客户端和服务器端&#xff0c;只有服务器端服务开启以后&#xff0c;才可以通过客户端登录MySQL服务端。 首先&#xff0c;以管理员身份运行“命令提示符”&#xff1a; &#xff08;1&#xff09;启动MySQL服务…

python井字棋游戏设计与实现

python实现井字棋游戏 游戏规则&#xff0c;有三个井字棋盘&#xff0c;看谁连成的直线棋盘多谁就获胜 棋盘的展现形式为 棋盘号ABC和位置数字1-9 输入A1 代表在A棋盘1号位数下棋 效果图如下 部分源码如下&#xff1a; 卫星工纵浩 白龙码程序设计&#xff0c;点 代码获取 …

海外短剧平台的局限性与优势:做平台还是选择CPS?

随着国内短剧市场的蓬勃发展&#xff0c;越来越多的目光开始聚焦在海外市场。不少企业和个人都看到了“文化输出”的巨大潜力&#xff0c;希望通过短剧这一形式&#xff0c;吸引海外的观众。然而&#xff0c;在进入海外市场时&#xff0c;我们面临着两种主要的选择&#xff1a;…

STM32 定时器 输入捕获

用于测频率测占空比 IC(Input Capture)输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变&#xff08;上升沿/下降沿&#xff09;时&#xff0c;会让当前CNT的值将被锁存到CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数…

2024年入职/转行网络安全,该如何规划?_网络安全职业规划

前言 前段时间&#xff0c;知名机构麦可思研究院发布了 《2022年中国本科生就业报告》&#xff0c;其中详细列出近五年的本科绿牌专业&#xff0c;其中&#xff0c;信息安全位列第一。 网络安全前景 对于网络安全的发展与就业前景&#xff0c;想必无需我多言&#xff0c;作为…

制造企业为什么要数字化转型?面临哪些困难?

如何界定制造企业 制造业&#xff08;Manufacturing Industry&#xff09;是指机械工业时代利用某种资源&#xff08;物料、能源、设备、工具、资金、技术、信息和人力等&#xff09;&#xff0c;按照市场要求&#xff0c;通过制造过程&#xff0c;转化为可供人们使用和利用的…

坐牢第二十七天(聊天室)

基于UDP的网络聊天室 一.项目需求&#xff1a; 1.如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2.如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息 3.如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 4.服务器可以发送系统信息…

8月16日笔记

只有DNS协议出网场景 DNS 协议是一种请求、应答协议&#xff0c;也是一种可用于应用层的隧道技术。DNS 隧道的工作原理很简单&#xff0c;在进行 DNS 查询时&#xff0c;如果查询的域名不在 DNS 服务器本机缓存中&#xff0c;就会访问互联网进行查询&#xff0c;然后返回结果。…

JavaScript基础知识(三)

样式修改 元素.style是对象的一种格式,用于通过设置元素的相关行内样式来设置css,也可以选择相关关联的样式来修改元素相关的样式. 要注意的是,选择相关的样式的时候,样式名是采用小驼峰写法而非是全部小写的方式 类名 添加类名: 元素.classList.add("classname") …

FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer

GSYVideoPlayer是一个国产的移动端视频播放器&#xff0c;它采用了IJKPlayer、Media3(EXOPlayer)、MediaPlayer、AliPlayer等四种播放器内核&#xff0c;支持弹幕、滤镜、广告等多项功能。 GSYVideoPlayer的Github主页为https://github.com/CarGuo/GSYVideoPlayer&#xff0c;截…