引言

​ 今天的每日一题原题是2643. 一最多的行,直接模拟,切除和最大的一行即可。更换成前几天遇到的更有意思的一题来写这个每日一题。

题目

968. 监控二叉树

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

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

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

示例 1:

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

示例 2:

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

提示:

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

思路

​ 我们要放置最少的摄像头,就要让每个摄像头都可以尽可能多的监控到节点。贪心的看,我们不应该在任何一个叶子节点放置摄像头。原因是,如果有一种最优解是在叶子节点放置摄像头,那么我去掉这个摄像头,放置在这个叶子节点的父节点,监控到的范围会比在叶子节点的摄像头范围更广,明显是更优的做法。

​ 有个上面这个大逻辑,我们可以根据每个节点上有无摄像头、以及有无监控分成3种状态(两两组合是4种,但是不可能出现有摄像头无监控,所以实际上是3种):

  • 0:无摄像头,无监控
  • 1:无摄像头,有监控
  • 2:有摄像头,有监控

对整棵树自下而上来看,根据左右子节点来决策当前节点的状态。

​ 空节点肯定是无摄像头,但是到底有无监控呢?根据我们一开始贪心得到的逻辑,我们不可能在叶子节点放置摄像头,由于空节点可以看到是叶子节点的子节点,所以,我们把空节点状态定义成1:无摄像头,有监控,有利于我们进行递归;

​ 如果左子节点或者右子节点的状态是0:无摄像头,无监控,那么当前节点必须放置摄像头,来监控这个状态为0的子节点,当前节点状态为2:有摄像头,有监控

​ 如果左子节点和右子节点都是1:无摄像头,有监控,那么当前节点不需要放置摄像头,且不会被某个子节点的摄像头监控到,当前节点状态是0:无摄像头,无监控

​ 如果左子节点或者右子节点有摄像头(排除掉某个子节点状态是0,上面已经讨论过了),此时当前节点会被这个子节点的摄像头监控到,当前节点的状态是1:无摄像头,有监控

​ 总结一下,当前节点的2个子节点,每个子节点可能有3种状态,排列后一共可能存在9种情况:

null: cur = 1
left = 0 || right = 0, 5种情况, cur = 2, ans++
left = 1, right = 1, 1种情况, cur = 0
left = 2 || right = 2, 3种情况, cur = 1

图解

代码

private int ans;

/**
* 每个节点可以有3种状态
* 0:无摄像头,无监控
* 1:无摄像头,有监控
* 2:有摄像头,有监控
*/
public int minCameraCover(TreeNode root) {
ans = 0;
int rootStatus = postOrder(root);
if (rootStatus == 0) {
// 根节点未被监控,需要在根节点再放1个摄像头
ans++;
}
return ans;
} private int postOrder(TreeNode node) {
if (node == null) {
// 空节点可以认为是叶子节点的子节点,由于叶子节点状态应该是0(贪心的思路,肯定有1种最佳方案,叶子节点上没有任何摄像头,因为放在叶子节点的父节点,肯定是更好的一个选择),所以空节点的状态,应该是1
return 1;
}
int left = postOrder(node.left);
int right = postOrder(node.right);
if (left == 0 || right == 0) {
ans++;
return 2;
} else if (left == 1 && right == 1) {
return 0;
} else {
return 1;
}
}

耗时

leetcode每日一题:监控二叉树的更多相关文章

  1. 【js】Leetcode每日一题-二叉树的堂兄弟节点

    [js]Leetcode每日一题-二叉树的堂兄弟节点 [题目描述] 在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处. 如果二叉树的两个节点深度相同,但 父节点不 ...

  2. 【JavaScript】Leetcode每日一题-递增顺序搜索树

    [JavaScript]Leetcode每日一题-递增顺序搜索树 [题目描述] 给你一棵二叉搜索树,请你 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没 ...

  3. 【js】Leetcode每日一题-叶子相似的树

    [js]Leetcode每日一题-叶子相似的树 [题目描述] 请考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 . 举个例子,如上图所示,给定一棵叶值序列为 (6, 7 ...

  4. 【js】Leetcode每日一题-制作m束花所需的最少天数

    [js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...

  5. 【JavaScript】Leetcode每日一题-在D天内送包裹的能力

    [JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...

  6. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  7. 【js】Leetcode每日一题-数组异或操作

    [js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...

  8. 【js】Leetcode每日一题-解码异或后数组

    [js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...

  9. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  10. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

随机推荐

  1. Mybatis插入数据后返回主键

    添加记录后获取主键ID,这是一个很常见的需求,特别是在一次前端调用中需要插入多个表的场景. 除了添加单条记录时获取主键值,有时候可能需要获取批量添加记录时各记录的主键值,MyBatis从3.3.1版本 ...

  2. C语言中的窗口滑动技术

    学习文章:C语言中的窗口滑动技术 滑动窗口法 C语言中的窗口滑动技术 循环几乎是每个复杂问题的一部分.太多的循环/嵌套循环会增加所需的时间,从而增加程序的时间复杂性.窗口滑动技术是一种计算技术,用于减 ...

  3. python 控制流程

    条件语句 if语法 if True: print("hello") print("world!") 输出: helloworld! 举例: "&quo ...

  4. 小程序uni-app中uview中select选择器第二次无法选中设置的默认值

    <u-select v-model="subjectFlag" title="选择科目" @confirm="okSubjecthander&q ...

  5. Git 忽略文件配置全解析

    Git 忽略文件配置全解析 在Git版本控制系统中,.gitignore文件扮演着至关重要的角色.它允许我们指定哪些文件或目录应该被Git忽略,即不被纳入版本控制之中.这对于避免提交敏感信息.构建产物 ...

  6. SecureCRT 屏幕输出行数设置

    第一步:打开设置 第二步:设置历史展示行数 第三步:保存后重启软件即可

  7. 如何配置 maven 编译插件的 JDK 版本

    普通maven项目配置编译器版本 参考maven官方文档 Setting the -source and -target of the Java Compiler maven有2种方法设置编译JDK版 ...

  8. Python类型提示完全指南:用类型安全重构你的代码,提升10倍开发效率

    title: Python类型提示完全指南:用类型安全重构你的代码,提升10倍开发效率 date: 2025/2/23 updated: 2025/2/23 author: cmdragon exce ...

  9. Gradle的安装及换源详细教程

    Gradle是一个基于JVM的构建工具,用于自动化构建.测试和部署项目. 1. 安装Gradle a. 首先,确保你已经安装了Java Development Kit (JDK),并且已经配置了JAV ...

  10. DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求

    DeepSeek 新的 LLM 推理方法 DeepSeek 通过强化学习(RL)提出了一种创新的改进大规模语言模型(LLM)推理能力的方法,这在他们最近关于 DeepSeek-R1 的论文中有详细介绍 ...