题目链接:968. 监控二叉树
题目描述
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0] 输出:1 解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0] 输出:2 解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
提示:
- 给定树的节点数的范围是
[1, 1000]
。 - 每个节点的值都是 0。
文章讲解:代码随想录
视频讲解:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题解1:贪心算法
思路:给叶子节点的父节点安装摄像头,之后每隔2个节点安装一个摄像头,最后将得到最少的摄像头。为每个节点定义状态,0为无覆盖,1为有摄像头,2为有覆盖,使用后序遍历自底向上返回节点状态。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minCameraCover = function(root) {
let res = 0;
// 定义状态,0为无覆盖,1为有摄像头,2为有覆盖
const postorder = function (node) {
if (!node) {
return 2; // 空节点视为有覆盖
}
const left = postorder(node.left);
const right = postorder(node.right);
// 左右孩子有1个无覆盖,则当前节点需要添加摄像头
if (left === 0 || right === 0) {
res++;
return 1;
}
// 左右孩子有1个有摄像头,则当前节点状态为有覆盖
if (left === 1 || right === 1) {
return 2;
}
// 左右孩子都有覆盖,则当前节点状态为无覆盖
return 0;
};
return postorder(root) === 0 ? res + 1 : res; // 如果根节点状态为无覆盖,则需要为根节点添加摄像头
};
分析:时间复杂度为 O(n),空间复杂度为 O(n)。
收获
练习了贪心算法的思路,同时回顾了二叉树操作。