代码随想录

前言

代码随想录算法训练营day37


一、Leetcode 968.监控二叉树 v

1.题目

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

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

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

示例 1:

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

示例 2:

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

提示:

 

css

复制代码

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

来源:力扣(LeetCode) 链接:leetcode.cn/problems/bi…

2.解题思路

方法一:动态规划

思路与算法

本题以二叉树为背景,不难想到用递归的方式求解。本题的难度在于如何从左、右子树的状态,推导出父节点的状态。

为了表述方便,我们约定:如果某棵树的所有节点都被监控,则称该树被「覆盖」。

假设当前节点为 rootroot,其左右孩子为 left,rightleft,right。如果要覆盖以 rootroot 为根的树,有两种情况:

 

css

复制代码

若在 rootroot 处安放摄像头,则孩子 left,rightleft,right 一定也会被监控到。此时,只需要保证 leftleft 的两棵子树被覆盖,同时保证 rightright 的两棵子树也被覆盖即可。 否则, 如果 rootroot 处不安放摄像头,则除了覆盖 rootroot 的两棵子树之外,孩子 left,rightleft,right 之一必须要安装摄像头,从而保证 rootroot 会被监控到。

根据上面的讨论,能够分析出,对于每个节点 rootroot ,需要维护三种类型的状态:

 

复制代码

状态 aa:rootroot 必须放置摄像头的情况下,覆盖整棵树需要的摄像头数目。 状态 bb:覆盖整棵树需要的摄像头数目,无论 rootroot 是否放置摄像头。 状态 cc:覆盖两棵子树需要的摄像头数目,无论节点 rootroot 本身是否被监控到。

根据它们的定义,一定有 a≥b≥ca≥b≥c。

对于节点 rootroot 而言,设其左右孩子 left,rightleft,right 对应的状态变量分别为 (la,lb,lc)(la​,lb​,lc​) 以及 (ra,rb,rc)(ra​,rb​,rc​)。根据一开始的讨论,我们已经得到了求解 a,ba,b 的过程:

 

css

复制代码

a=lc+rc+1a=lc​+rc​+1 b=min⁡(a,min⁡(la+rb,ra+lb))b=min(a,min(la​+rb​,ra​+lb​))

对于 cc 而言,要保证两棵子树被完全覆盖,要么 rootroot 处放置一个摄像头,需要的摄像头数目为 aa;要么 rootroot 处不放置摄像头,此时两棵子树分别保证自己被覆盖,需要的摄像头数目为 lb+rblb​+rb​。

需要额外注意的是,对于 rootroot 而言,如果其某个孩子为空,则不能通过在该孩子处放置摄像头的方式,监控到当前节点。因此,该孩子对应的变量 aa 应当返回一个大整数,用于标识不可能的情形。

最终,根节点的状态变量 bb 即为要求出的答案。

3.代码实现

 

java

复制代码

class Solution { public int minCameraCover(TreeNode root) { int[] array = dfs(root); return array[1]; } public int[] dfs(TreeNode root) { if (root == null) { return new int[]{Integer.MAX_VALUE / 2, 0, 0}; } int[] leftArray = dfs(root.left); int[] rightArray = dfs(root.right); int[] array = new int[3]; array[0] = leftArray[2] + rightArray[2] + 1; array[1] = Math.min(array[0], Math.min(leftArray[0] + rightArray[1], rightArray[0] + leftArray[1])); array[2] = Math.min(array[0], leftArray[1] + rightArray[1]); return array; } }

二、Leetcode 738.单调递增的数字

1.题目

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

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

示例 1:

输入: n = 10 输出: 9

示例 2:

输入: n = 1234 输出: 1234

示例 3:

输入: n = 332 输出: 299

提示:

 

复制代码

0 <= n <= 109

来源:力扣(LeetCode) 链接:leetcode.cn/problems/mo…

2.解题思路

方法一:贪心

我们可以从高到低按位构造这个小于等于 nn 的最大单调递增的数字。假设不考虑 nn 的限制,那么对于一个长度为 kk 的数字,最大单调递增的数字一定是每一位都为 99 的数字。

记 strN[i]strN[i] 表示数字 nn 从高到低的第 ii 位的数字(ii 从 00 开始)。

如果整个数字 nn 本身已经是按位单调递增的,那么最大的数字即为 nn。

如果找到第一个位置 ii 使得 [0,i−1][0,i−1] 的数位单调递增且 strN[i−1]>strN[i]strN[i−1]>strN[i],此时 [0,i][0,i] 的数位都与 nn 的对应数位相等,仍然被 nn 限制着,即我们不能随意填写 [i+1,k−1][i+1,k−1] 位置上的数字。为了得到最大的数字,我们需要解除 nn 的限制,来让剩余的低位全部变成 99 ,即能得到小于 nn 的最大整数。而从贪心的角度考虑,我们需要尽量让高位与 nn 的对应数位相等,故尝试让 strN[i−1]strN[i−1] 自身数位减 11。此时已经不再受 nn 的限制,直接将 [i,k−1][i,k−1] 的位置上的数全部变为 99 即可。

但这里存在一个问题:当 strN[i−1]strN[i−1] 自身数位减 11 后可能会使得 strN[i−1]strN[i−1] 和 strN[i−2]strN[i−2] 不再满足递增的关系,因此我们需要从 i−1i−1 开始递减比较相邻数位的关系,直到找到第一个位置 jj 使得 strN[j]strN[j] 自身数位减 11 后 strN[j−1]strN[j−1] 和 strN[j]strN[j] 仍然保持递增关系,或者位置 jj 已经到最左边(即 jj 的值为 00),此时我们将 [j+1,k−1][j+1,k−1] 的数全部变为 99 才能得到最终正确的答案。

3.代码实现

 

java

复制代码

class Solution { public int monotoneIncreasingDigits(int n) { char[] strN = Integer.toString(n).toCharArray(); int i = 1; while (i < strN.length && strN[i - 1] <= strN[i]) { i += 1; } if (i < strN.length) { while (i > 0 && strN[i - 1] > strN[i]) { strN[i - 1] -= 1; i -= 1; } for (i += 1; i < strN.length; ++i) { strN[i] = '9'; } } return Integer.parseInt(new String(strN)); } }

作者:东离与糖宝
链接:https://juejin.cn/post/7245173689154224187
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

相关文章

【Python】Python语言基础(上)

第一章 前言 1. Python简介 Python语言并不是新的语言&#xff0c;它早于HTTP 1.0协议5年&#xff0c;早于Java语言 4年。 ​ Python是由荷兰人Guido van Rossum&#xff08;吉多范罗苏姆&#xff09;于1989年圣诞节期间在阿姆斯特丹休假时为了打发无聊的假期而编写的一个脚本…

车载电子电器架构 —— 国产基础软件现在与未来

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

bash: /usr/bin/cmake: No such file or directory

问题描述 当在linux 下 源码安装 cmake &#xff0c;验证安装 cmake --version&#xff0c; 出现以下错误&#xff1a; bash: /usr/bin/cmake: No such file or directory 解决方法&#xff1a; 将编译生成的 cmake 复制到 /usr/bin 文件夹下 cp ./cmake-3.x/bin/cmake …

idea自动封装方法

例如 package com.utils;import java.lang.reflect.Field; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle;/*** author hrui* date 2023/10/13 13:49*/ public class DBUtils {private static ResourceBundle bund…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例docker部署及应用(七)

八、华为云耀云服务器L实例docker、docker-compose安装及部署MySQL、Redis应用&#xff1a; 随着云原生、容器化、微服务、K8S等技术的发展&#xff0c;容器 docker 也逐渐在企业团队实践中大量的使用。它可以提供了一套标准化的解决方案&#xff0c;极大地提升了部署、发布、运…

2023年中国视频流媒体行业发展历程及趋势分析:未来市场规模趋于平稳[图]

随着移动通信的发展和视频内容产业供给端的繁荣&#xff0c;流媒体视频平台已经成为互联网用户上网时长最长的应用之一。在线视频行业经历了十几年的规范发展阶段&#xff0c;在各大头部平台百花齐放的现状下&#xff0c;难以实现一家独大&#xff0c;但部分平台有领先优势&…

acwing算法基础之基础算法--整数离散化算法

目录 1 知识点2 模板 1 知识点 整个范围很大&#xff0c;但存在的数据点很少。比如从 − 1 0 9 -10^9 −109到 1 0 9 10^9 109&#xff0c;但总共只有 1 0 6 10^6 106个数。 可以采用离散化的思想来做&#xff0c;即将离散的大数值映射成连续的小数值&#xff08;一般是 1 , …

软考高级架构师下篇-18大数据架构理论设计与实践

目录 1. 引言2. 传统数据处理系统的问题1.传统数据库的数据过载问题2.大数据的特点3.大数据利用过程4.大数据处理系统架构分析3.典型的大数据架构1. Lambda架构2.Kappa架构3. Lambda架构与Kappa架构的对比4.大数据架构的实践1.大规模视频网络2.广告平台3.公司智能决策大数据系统…

整理redis写入string类型的缓存的方法

第一种存储方式&#xff1a;JSON方法 可以使用Redis的序列化方法将数组转换为字符串&#xff0c;然后将其写入Redis中的String类型缓存。常见的序列化方法有JSON和PHP自带的序列化函数serialize和unserialize。 以下是一个示例代码&#xff0c;将一个数组写入Redis中&#xf…

数字孪生技术:新零售的未来之路

随着科技的不断进步&#xff0c;新零售产业正经历着巨大的变革。数字孪生作为一种新兴技术正在加速这一变革的进程。它不仅为新零售企业带来了更高效的运营方式&#xff0c;还为消费者提供了更个性化、便捷的购物体验。那么&#xff0c;数字孪生技术究竟如何在新零售产业中发挥…

HDLbits:Fsm onehot

这道题理解有误&#xff0c;以为s010b0000000001&#xff0c;s010b0000000010&#xff0c;写成了如下的代码&#xff08;有误&#xff09;&#xff1a; module top_module(input in,input [9:0] state,output [9:0] next_state,output out1,output out2);parameter s010b00000…

分享关于职场心态

1.解决问题而不是解释原因 2.秉承工匠思维而不是激情思维 什么是工匠思维&#xff1f; 工匠思维&#xff08;The craftsman mindset&#xff09;对待职业生涯的一种方式&#xff1b;是以产出为中心的职业观&#xff0c;关注自己给世界&#xff08;工作&#xff09;带来的价值…

免密码方式获取Hive元数据

前言 开发中可能用到hive的元数据信息 &#xff0c;如获取hive表列表、hive表字段、hive表数据量大小、hive表文件大小等信息&#xff0c;要想获取hive元数据信息即需要hive元数据库的账号及密码&#xff0c;此次提供的是一种不需要hive元数据库密码及可获取元数据信息的方式 …

观察者模式、订阅者发布者模式、vtk中的观察者模式

文章目录 什么是观察者模式vtk是如何实现的观察者模式.AddObserver什么时候使用观察者模式&#xff1f;什么使用订阅发布者模式?观察者模式的实现订阅发布者的实现总结知识补充: 什么是观察者模式 用于在对象之间建立一对多的依赖关系&#xff0c;当一个对象的状态发生变化时…

用一个结构去分割二维空间

( A, B )---5*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有5个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A 中有5个点&#xff0c;B全是0&#xff0c;排列组合&#xff0c;统计迭代次数并排序。 其中5-x有3组数据 4-x 差值结构 迭代次数 5-x 差值结构 …

JAVA之多线程

文章目录 进程与线程多线程的生命周期多线程的实现方式 进程与线程 进程是指运行中的应用程序&#xff0c;每一个进程都有自己独立的内存空间&#xff1b;线程是指进程中的一个执行流程&#xff0c;有时也称为执行情景&#xff1b;一个进程可以由多个线程组成&#xff0c;即在…

springboot中如何加载测试专用属性

测试 加载测试专用属性 加载测试专用配置 Web环境模拟测试 数据层测试回滚 测试用例数据设定 1.在启动测试环境时可以通过properties参数设置测试环境专用的属性 SpringBootTest(properties {"test.proptestValue1"}) public class PropertiesAndArgsTest {Value(…

Web应用-Thinkphp框架-开发指南

Thinkphp框架 二级导航分类&#xff0c;模板继承&#xff0c;内置标签Public 修改MVC模块化 ——访问机制传参加载模版模版引入 分离Runtime 缓存文件管理员添加数据验证及验证场景 控制器 validate 在sql执行&#xff08;敏感操作&#xff09;之前验证数据模板 分页数据表连接…

[MoeCTF 2023] web题解

文章目录 webhttpcookie彼岸的flagmoe图床大海捞针夺命十三枪 web http 连接到本地后&#xff0c;题目给了我们任务 第一个是要求我们GET传参UwUu第二个是要求我们POST传参Luvu第三个是要求我们cookie值为admin第四个是要求我们来自127.0.0.1第五个是要求我们用MoeBrowser浏…

ajax实现原理

网页应用能够快速地将增量更新呈现在用户界面上&#xff0c;而不需要重载&#xff08;刷新&#xff09;整个页面。这使得程序能够更快地回应用户的操作 Ajax的实现原理 创建Ajax对象 传入请求方式和请求地址 发送请求 获取服务器与客户端的响应数据 xhr.responseText // 1…