算法学习打卡day36| 738.单调递增的数字、 968.监控二叉树、贪心算法阶段学习总结

738.单调递增的数字

力扣题目链接
题目描述:
当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。
示例 1:
输入: n = 10
输出: 9

示例 2:
输入: n = 1234
输出: 1234
示例 3:
输入: n = 332
输出: 299

思路:

  • 暴力方法很好想,就是倒序遍历,然后判断每个数字是否符合条件就行了,但是提交后会超时😄。
  • 细想一下,如果每次只是–1,然后再去判断的话,那么在上一个数字不符合条件时,那个位置之前做的所有判断就白做了。
  • 那么能不能把之前的利用起来呢? 当然可以!我们把数字用库函数转换为字符串,然后去逐字符倒序比较(注意是倒序,不能是正序),遇到s[i - 1] > s[i] 的情况就让s[i - 1] - 1,然后让s[i]之后色所有数字都变为9,只有这样才能保证一直符合条件也能保证是最大值(而不是把s[i - 1]减到s[i] - 1,然后s[i]后面都不动,很显然只让s[i - 1] - 1然后后面所有值变为9更大一些,本题的需求是求最大值!)
  • 为什么不是正序遍历?
    • 因为正序遍历后,假如此时s[i - 1]s[i]是符合递增条件的,那后面万一s[i + 1] < s[i]的话,必须让s[i] - 1,那么此时可能s[i - 1] > s[i]了,全面的又不符合条件了,唯有倒序遍历,后面的值一直比前面值大。

代码实现:

int monotoneIncreasingDigits(int n) {if (n < 10) return n;string s = to_string(n);int flag = s.size();for (int i = s.size() - 1; i > 0; --i) {if (s[i] < s[i - 1]) {s[i - 1]--;flag = i;}}//为了减少循环里多做的重复修改动作,直接设置一个flag位,在退出后,统一修改for (int j = flag; j < s.size(); ++j) {s[j] = '9';}return stoi(s);}

968.监控二叉树

力扣题目链接
题目描述:
给定一个二叉树,我们在树的节点上安装摄像头。

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

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

示例 1:
在这里插入图片描述

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

思路:

  • 这道题是贪心 + 二叉树的结合,在哪个节点放摄像机才能让摄像机数量整体保证最小?那根据贪心的思想肯定是放中间节点最好,因为其可以辐射两个子节点和一个父节点,叶子节点肯定不能放,因为它只能辐射自己的父节点,不可能让我们的总量最小。
  • 那根据二叉树的做题思路,先判断用哪种遍历方式,因为我们不在叶子节点放摄像头,那么肯定需要判断左右子树的结果,是空还是叶子节点还是非叶子节点,肯定是左 > 右 > 中了,后序遍历走起!
  • 决定了遍历方式后,就要决定返回值,参数、函数退出逻辑以及单层递归逻辑,递归三部曲
    • 函数参数:参数肯定是树节点root,和传出参数count表示摄像机个数。
    • 返回值:由于我们需要根据左右子树的函数返回值来判断当前节点是否需要安装摄像头,那么返回值肯定是左右子节点的状态了,状态无非是:安装或者未安装,但是未安装其实是有两种状态的,如果子节点安装了,那父节点就不必要安装了,此时是被覆盖而不用安装,还有一种就是没有被覆盖也没有安装的(比如叶子节点)所以,其实一共三种状态:未覆盖、安装、被覆盖,我们分别用0,1,2来表示,分别需要有不同的应对处理方式。
    • 函数退出条件:
      • 当遇到空节点时,返回2,为什么?因为空节点是不用管他的,就当它被覆盖了,但是肯定不能是0和1吧?
      • 当遇到叶子节时,返回0,这个很好理解,叶子节点就要被它的父节点去覆盖。
      • 当遇到非叶子节点,直接交给递归。(这一步就属于单步处理逻辑了,因为不用退出我们需要处理它的返回值)
    • 单步处理逻辑:分别递归左右子节点,然后取其返回值进行比较
      • left == 0 || right == 0)时,我们需要安装摄像头,因为子节点未覆盖,直接count++,然后返回 1。
      • left == 1 || right == 1时,我们不需要安装摄像头了,因为子节点安装了,但是当前节点被覆盖了,所以返回 2。
      • 剩下就是等于 2 的情况了,不用单独判断,直接返回 0。为啥? 因为子节点都是被覆盖,而当前节点最好交给父节点去判断,如果当前节点安装了摄像头就和叶子节点一个逻辑了,相当于只辐射了父节点,两个子节点人家已经被别的节点覆盖了!
    • 另外注意根节点的判断,因为没人能处理root的返回值,只能交给调用递归函数的主函数了!
  • 自己第一次的做题思路:想到了后序遍历,也想到了叶子节点不能放摄像头,就是没想到返回值有三种状态,只是返回了true或者false,安装了就返回true,未安装就返回false,然后处理返回值的时候,只要左右返回值有true就当前节点就返回false,因为是子节点安装了嘛,我肯定被辐射到了!左右节点返回值都是false,我自己就安装一个,其实这也是错误的地方,因为无法判断两个子节点是因为被覆盖而返回false,还是因为未被覆盖而返回的false

代码实现:

int traverse(TreeNode* root, int& count) {if (root == nullptr) return 2;if (!root->left && !root->right) return 0;int left =  traverse(root->left, count);int right = traverse(root->right, count);if (left == 0 || right == 0) {count++;return 1;}if (left == 1 || right == 1)    return 2;return 0;} int minCameraCover(TreeNode* root) {int count = 0;if (traverse(root, count) == 0) {count++;}return count;}

贪心算法阶段学习总结

  • 学了一周贪心,除了覆盖问题有点套路外,其实题还是懵懵懂懂的,感觉做出来的题和贪心没啥大关系,哎,多练吧😑
  • 下面做个总结
    • 什么是贪心?
      • 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
      • 大概分为四个步骤分析问题:
        1. 将问题分解为若干个子问题
        2. 找出适合的贪心策略
        3. 求解每一个子问题的最优解
        4. 将局部最优解堆叠成全局最优解
      • 这个很虚无缥缈,一般情况怎么拆解子问题都不好想,凭感觉如果觉得可以通过局部最优实现全局最优,且列举不出来反例,就可以试试贪心算法,可能做的题不多,体会不深很深😄。
    • 简单题:
      • 分发饼干:这道题就是对胃口数组和饼干数组排序,然后尽量把小饼干分给小胃口,大饼干分给大胃口,注意只用一个循环的写法,怎么写?
      • K次取反后最大化的数组和:这道题要对数组根据绝对值排序,然后每次先反转负数,等都反转为正数后,取最小值重复反转就可以保证整体值最大,贪起来。
      • 贪心算法:柠檬水找零, 这个题也很简单,就是把三种金额的币分别存起来,遇到20优先找10和5,没有10再找三个5,其他没有什么难度。
    • 中等题:
      • 单调递增的数字:就是上面做的第一道题,数字转换为字符串的处理思路,可以省去取余和除法操作!然后遇到不符合情况-1而不是减到比后一位少1
      • 股票题:股票题最好用动态规划做,就只有一个题用贪心,性能会好一点,直接拿到相邻两天的股票价格差,取正数相加即可,可以在遍历的途中就取最值,得结果了,也可以滑动窗口。
      • 区间覆盖问题:
        • 一共是六道题,重叠区间四道题,有:435. 无重叠区间、763.划分字母区间、56. 合并区间、452. 用最少数量的箭引爆气球,除了划分字符串,其他三道题都是套模版,字母区间这道题就是记录每个字母的右边界,然后循环不断更新right,直到i走到right就是一个子序列
        • 还有两道跳跃游戏题 也属于区间问题,跳跃游戏是不断更新自己能走到的最远处,只要最远处包含了数组最后一个元素就返回true,而跳跃游戏2是不仅要道最远处还要使得步数最小,那么就每次先走到第一步能走到的最远处,然后走的途中记录第二步能到的最远处,以便更新,第二部的右界,每次走到了右界,就判断下下一步能不能走到数组结尾,能得话步数+1退出 ,其实感觉和划分字母子区间的思路类似,都是不断更改上界,直到上界遇到某个临界值或者走到上界了要怎么处理。
      • 两个维度权衡问题
        • 分发糖果:先满足左或右边界,再满足另一边
        • 根据身高重建队列:这道题必须先满足身高,然后再根据第二个元素去插入即可,注意这道题的链表实现,涉及到vector扩容问题,还有注意身高相同时要,怎么排序
    • hard题目
      • 加油站:这道题思路很难想,但是实现很简单,就是一个循环,然后不断求出当前剩余油是否是正数,如果是负数,那么起点一定在当前加油站之后。
      • 最大连续子序和:和加油站一个思路,只要出现负数就不要了,从负数下一个点开始算,因为出现负数就会令整体和变小。
      • 摆动序列:这道题就有点难度了,贪心思想贪的点在于找到一段序列让每个坡都只有开头和结束两个点,因为要比较坡度是否一样,就要和前一组之差比较,只要符号不同就算符合条件,pre_diff > 0 && cur_diff < 0 || pre_diff < 0 && cur_diff > 0,但要注意平坡的出现,以及什么时候更新pre_diff
      • 监控二叉树:后序+贪心,注意递归函数返回值的三种状态

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

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

相关文章

虹科案例 | AR内窥镜手术应用为手术节约45分钟?

相信医疗从业者都知道&#xff0c;在手术室中有非常多的医疗器械屏幕&#xff0c;特别是内窥镜手术室中医生依赖这些内窥镜画面来帮助病患进行手术。但手术室空间有限&#xff0c;屏幕缩放位置相对固定&#xff0c;在特殊场景下医生观看内窥镜画面时无法关注到病患的状态。这存…

mysql数据库【基础】

本教程适合有一定基础的人&#xff0c;我是用来复习mysql数据&#xff0c;跟着教程走一遍熟悉一下mysql的语句 数据准备 下面的数据库查询语句都是基于此表进行查询的 员工表 创建表&#xff1a; -- 创建表 drop table if exists emp; create table emp (id int …

离散傅里叶变换中的能量守恒公式(帕斯瓦尔定理)及其程序举例验证

离散傅里叶变换中的能量守恒公式&#xff08;帕斯瓦尔定理&#xff09;及其程序举例验证 一、 离散傅里叶变换中的能量守恒公式 离散傅里叶变换中的能量守恒公式&#xff1a; ∑ n 0 N − 1 ∣ x [ n ] ∣ 2 1 N ∑ k 0 N − 1 ∣ X [ k ] ∣ 2 (1) \sum\limits_{n 0}^{N…

HNU-算法设计与分析-讨论课1

第一次小班讨论 &#xff08;以组为单位&#xff0c;每组一题&#xff0c;每组人人参与、合理分工&#xff0c;ppt中标记分工&#xff0c;尽量都有代码演示&#xff09; 1.算法分析题 2-10、2-15(要求&#xff1a;有ppt&#xff08;可代码演示&#xff09;) 2.算法实现题 2-4、…

什么是NPM(Node Package Manager)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

rhcsa-数据流和重定向

cp cp 选项 源文件 目标文件 ****-a 复制目录的所有信息&#xff08;保留文件信息&#xff09; -p保留原文件的权限&#xff0c;所有者以及时间戳的信息 -r复制目录及所有子目录的所有文件 例&#xff1a; cp -p 复制的源文件 复制的目标路径 mv 作用&#xff…

Azure 机器学习 - 使用 Visual Studio Code训练图像分类 TensorFlow 模型

了解如何使用 TensorFlow 和 Azure 机器学习 Visual Studio Code 扩展训练图像分类模型来识别手写数字。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员…

滤波器及其离散化

原理介绍 令 A aT 一阶低通滤波器&#xff08;离散化&#xff09; - 知乎 (zhihu.com) 【精选】低通滤波器总结_低通滤波器 计算公式 离散_奇妙水果的博客-CSDN博客 MATLAB数值仿真FOC矢量控制_matlab foc模型_奇妙水果的博客-CSDN博客

Day42 力扣动态规划 :123.买卖股票的最佳时机III |188.买卖股票的最佳时机IV

Day42 力扣动态规划 :123.买卖股票的最佳时机III &#xff5c;188.买卖股票的最佳时机IV 123.买卖股票的最佳时机III第一印象看完题解的思路dp数组&#xff1a;递推公式&#xff1a;初始化遍历顺序 实现中的困难感悟代码 188.买卖股票的最佳时机IV第一印象初始化递推公式看完题…

wireshark捕获DNS

DNS解析&#xff1a; 过滤项输入dns&#xff1a; dns查询报文 应答报文&#xff1a; 事务id相同&#xff0c;flag里 QR字段1&#xff0c;表示响应&#xff0c;answers rrs变成了2. 并且响应报文多了Answers 再具体一点&#xff0c;得到解析出的ip地址&#xff08;最底下的add…

Kafka、RabbitMQ、RocketMQ中间件的对比

消息中间件现在有不少&#xff0c;网上很多文章都对其做过对比&#xff0c;在这我对其做进一步总结与整理。 RocketMQ 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件&#xff0c;使用Mysql作为消息存储媒介&#xff0c;可完全水平扩容&#xff0c;为了进一步降低成…

nacos在linux中的安装、集群的配置、mysql生产配置

1.下载和安装 官方下载地址&#xff1a;https://github.com/alibaba/nacos/releases&#xff0c;根据自己需要的本版去下载就行 下载的是 .tar.gz 后缀的文件是linux版本的 使用tar命令解压&#xff0c;完成之后是一个nacos的文件夹 和windows下的文件夹目录是一样的 要启…

NumPy 相关函数

本篇文章介绍了Python中NumPy库的相关函数 np.corrcoef() 函数。 NumPy 中的相关性 相关系数是一个数字值&#xff0c;表示数据集给定特征之间的关系。 相关性可以是正相关&#xff0c;这意味着它们具有直接关系&#xff0c;并且一个特征的增加会导致另一个特征的增加。 负相…

创建ABAP数据库表和ABAP字典对象-创建表01

创建表 创建表在你的Package包中 选择(右键单击)包并从上下文菜单中选择New > Other ABAP Repository Object: 2.输入过滤器文本表>数据库表&#xff0c;然后选择Next。 3.输入一个名称&#xff0c;例如ZTRAINING_XXX(一般是具体的项目描述XXX)&#xff0c;然后选择Nex…

当你在浏览器地址栏输入一个URL后,将会发生的事情?个人笔记

客户端 在浏览器输入 URL 回车之后发生了什么&#xff08;超详细版&#xff09; - 知乎 (zhihu.com) 大致流程是&#xff1a; URL 解析DNS 查询TCP 连接处理请求接受响应渲染页面 1.URL解析 地址解析&#xff1a; 首先判断你输入是否是一个合法的URL还是一个待搜索的关键…

5.5 TCP报文段的首部格式

思维导图&#xff1a; 5.5 TCP报文段的首部格式 基本概念 TCP报文段&#xff1a;包含首部和数据两部分&#xff0c;首部至少20字节。作用&#xff1a;首部字段定义了TCP的功能和行为。长度&#xff1a;首部长度可变&#xff0c;基础首部20字节&#xff0c;可添加选项。 首部…

《算法通关村——缓存机制了解LRU实现》

《算法通关村——缓存机制了解LRU实现》 介绍 LRU是"Least Recently Used"&#xff08;最近最少使用&#xff09;的缓存机制&#xff0c;它是一种常用的缓存算法&#xff0c;用于管理缓存中的数据项。LRU缓存机制的基本思想是&#xff0c;当缓存达到其容量限制时&a…

【Tricks】PC端微信输入时,文本出现右对齐情况怎么恢复

应该是摁到某个快捷键&#xff0c;于是光标就变成如下图所示的样子&#xff1a; 如果再输入字符&#xff0c;则字符就会变成下图所示的样子&#xff08;对齐输入框右侧&#xff09;&#xff1a; 解决办法&#xff1a;ctrl J 解决办法&#xff1a;ctrl J 解决办法&#xff1…

5.2 用户数据报协议UDP

思维导图&#xff1a; 课程笔记&#xff1a;5.2 用户数据报协议UDP 5.2.1 UDP概述 一、UDP基本概念 无连接协议&#xff1a;UDP是一个简单的面向数据报的传输层协议&#xff0c;不需要在数据传输前建立连接&#xff0c;故减少开销和延迟。复用/分用&#xff1a;UDP允许多个应…

我的ChatGPT的几个使用场景

示例一&#xff0c;工作辅助、写函数代码&#xff1a; 这里展示了一个完整的代码&#xff0c;修正&#xff0c;然后最终输出的过程。GPT具备足够丰富的相关的小型代码生成能力&#xff0c;语法能力也足够好。这类应用场景&#xff0c;在我的GPT使用中&#xff0c;能占到65%以上…