算法学习打卡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
      • 监控二叉树:后序+贪心,注意递归函数返回值的三种状态

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

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

相关文章

洗地新天花板:CEYEE希亦顶配机皇T800 Pro洗地机多点发力上市开售

2023年11月1日&#xff0c;CEYEE希亦正式发布高端清洁产品无线洗地机希亦T800 PRO&#xff0c;创新性地实现了洗地场景深度清洁体验的新突破&#xff0c;彻底解决了清洁行业20多年来技术发展难题&#xff0c;颠覆式引领行业向水汽混动时代迈进&#xff0c;推动了整个市场向“智…

从0到1了解metasploit上线原理

在渗透的过程中拿到权限后通常会进行上线cs/msf的操作&#xff0c;我们了解上线的原理后&#xff0c;无论是对编写远控&#xff0c;还是绕过杀软帮助都很大。 前言 在渗透的过程中拿到权限后通常会进行上线cs/msf的操作&#xff0c;我们了解上线的原理后&#xff0c;无论是编…

服务器基础

目录 服务器介绍&#xff1a; 服务器定义&#xff1a; 服务器特点&#xff1a; 服务器架构&#xff1a; 按硬件形态的服务器分类&#xff1a; 华为TaiShan 200服务器的硬件结构&#xff1a; 服务器关键技术&#xff1a; IPMI协议&#xff08;Intelligent Platform Manag…

Oracle数据库创建Sequence序列的基本使用

1.作用就是批量插入数据的时候可以给一个主键 sequence dose not exist_sequence not exist_拒—绝的博客-CSDN博客 Oracle创建Sequence序列_TheEzreal的博客-CSDN博客 Oracle序列&#xff08;sequence&#xff09;创建失败&#xff0c;无法取值&#xff08;.nextval&#x…

【OpenCV实现图像:用Python生成图像特效,报错ValueError: too many values to unpack (expected 3)】

文章目录 概要读入图像改变单个通道黑白特效颜色反转将图像拆分成四个子部分 概要 Python是一种功能强大的编程语言&#xff0c;也是图像处理领域中常用的工具之一。通过使用Python的图像处理库&#xff08;例如Pillow、OpenCV等&#xff09;&#xff0c;开发者可以实现各种各…

前端css介绍

CSS介绍 CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;它就会按照这个样式表来对文档进行格式化&#xff08;渲染&#xff09;。 CSS语法 CSS实例 每个CSS样式由两个组成部分&#xff1a;选择器和…

matlab 计算Ax=b的解,解线性方程组的现成工具

只写了最简单的方式&#xff0c;其中b需要是列向量&#xff0c;用分号隔开元素&#xff1b; octave:7> A[1,2; 1.0001, 2;] A 1.0000 2.00001.0001 2.0000octave:8> b[3; 3.0001;] b 3.00003.0001octave:9> xA\b x 1.00001.0000octave:10> b-A*x ans 00octave:…

深入探究Vue.js生命周期及其应用场景

当谈到Vue.js的生命周期时&#xff0c;我们指的是组件在创建、更新和销毁过程中发生的一系列事件。了解Vue的生命周期对于开发人员来说是至关重要的&#xff0c;因为它们提供了一个机会来执行特定任务&#xff0c;并在不同的阶段处理组件。 Vue的生命周期可以分为八个不同的阶…

Tigger绕过激活锁/屏幕锁隐藏工具,支持登入iCloud有消息通知,支持iOS12.0-14.8.1。

绕过激活锁工具Tigger可以用来帮助因为忘记自己的ID或者密码而导致iPhone/iPad无法激活的工具来绕过自己的iPhone/iPad。工具支持Windows和Mac。 工具支持的功能&#xff1a; 1.Hello界面两网/三网/无基带/乱码绕过&#xff0c;可以完美重启&#xff0c;支持iCloud登录、有消…

关于服务端构件模型的典型解决方案

关于服务端构件模型的典型解决方案包括 适用于应用服务器的EJB模型&#xff08;Sun公司J2EE的一部分&#xff09;和COM模型&#xff08;微软公司&#xff09;&#xff0c; 以及适用于Web服务器的servlet模型&#xff08;基于Sun公司JSP技术&#xff09;和Visual Basic及其他技…

uniapp leven系列原生插件(1)

目录 1.乐橙摄像机播放插件(云台对讲版) 插件介绍 插件地址 预览图片 ​编辑 2.乐橙摄像机播放插件(子账号云台对讲版) 插件介绍 插件地址 预览图片 ​编辑 3.无预览静默拍照 插件介绍 插件地址 预览图片 4.视频图片选择安卓原生插件 插件介绍 插件地址 预览图…

RoCEv2网络部署----Mellanox网卡配置

Mellanox 网卡配置RoCEv2步骤&#xff0c; 1. 设置RDMA CM 模式v2 cma_roce_mode -d mlx5_1 -p 1 -m 2 检查RDMA CM的RoCE模式 2. 开启 DCQCN 在priority 3 echo 1 > /sys/class/net/ens1np0/ecn/roce_np/enable/3 echo 1 > /sys/class/net/ens1np0/ecn/roce_rp/enable…

天线测试解决方案-毫米波片上天线测量系统

毫米波片上天线测量系统 方案概述&#xff1a; 毫米波片上天线测量系统频率范围覆盖8GHz&#xff5e;110GHz&#xff08;可扩展至500GHz&#xff09;&#xff0c;具有频率覆盖范围宽、动态范围大、馈电形式灵活、结构紧凑、测试参数全面等特点。系统采用通用化、模块化设计思想…

生态扩展:Flink Doris Connector

生态扩展&#xff1a;Flink Doris Connector 官网地址&#xff1a; https://doris.apache.org/zh-CN/docs/dev/ecosystem/flink-doris-connector flink的安装&#xff1a; tar -zxvf flink-1.16.0-bin-scala_2.12.tgz mv flink-1.16.0-bin-scala_2.12.tgz /opt/flinkflink环境…

Modelsim 使用教程(2)——Basic Simulation

一、概述 在本文中&#xff0c;我们将介绍Modelsim基本的仿真流程&#xff0c;包括有&#xff1a; Create the Working Design Library&#xff08;创建工具库&#xff09; Compile the Design Units&#xff08;编译设计单元&#xff09; Optimize the Design&#xff08;优化…

arcgis将合并(组合)要素拆分的方法

1、打开一幅图&#xff0c;发现两块区域被连接成一块区域&#xff0c;如下&#xff1a; 2、在可编辑状态下&#xff0c;进行拆分&#xff0c;先选中待拆分要素&#xff0c;如下&#xff1a; 3、拆分后&#xff0c;如下&#xff1a;

C++初阶 类和对象(上)

前言&#xff1a;C初阶系列&#xff0c;每一期博主都会使用简单朴素的语言将对应的知识分享给大家&#xff0c;争取让所有人都可以听懂&#xff0c;C初阶系列会持续更新&#xff0c;上学期间将不定时更新&#xff0c;但总会更的 目录 一、什么是面向对象编程 二、什么是类和如…

白银期货投资指南,轻松搞定白银投资

在今天的金融市场中&#xff0c;白银已成为备受瞩目的投资选择。不仅如此&#xff0c;白银还是避险资产的首选之一&#xff0c;兼具保值和增值的潜力。万洲金业将为您提供一份白银期货投资指南&#xff0c;让您轻松了解白银投资&#xff0c;助力在白银交易市场获得潜在收益。 …

mpp解码详解

解码器数据流接口 一. decode_put_packet 输入码流的形式&#xff1a;分帧与不分帧 MPP 的输入都是没有封装信息的裸码流&#xff0c;裸码流输入有两种形式&#xff1a; 不分帧 这种方式是已经按帧分段的数据&#xff0c;即每一包输入给 decode_put_packet 函数的 MppPacket 数…

Spring事务失效的几种情况及其解决方案

Spring事务失效的几种情况及其解决方案 方法权限修饰符不是public Transactional 使用的是 Spring AOP 实现的&#xff0c;而 Spring AOP 是通过动态代理实现的&#xff0c;而 Transactional 在生成代理时会判断&#xff0c;如果方法为非 public 修饰的方法&#xff0c;则不生…