LeetCode:地址
题目要求
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入: [0,0,null,0,0]
输出: 1
解释: 如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
提示:
- 给定树的节点数的范围是
[1, 1000]。 - 每个节点的值都是 0。
思路
第一步:确定节点3个状态, 0代表未被监视; 1代表被监视; 2代表已安装摄像头; 第二步:后序遍历;先处理2个子节点再处理父节点; 第三步:根据子节点的状态返回父节点的状态; 1.子节点有一个状态为0,则父节点返回 2 父节点需要一个摄像头 res++(根据贪心思想 由上面的节点监控下面的节点比较省摄像头); 2.左右2个子节点状态都是1,则父节点返回0 (因为子节点都没有摄像头,所以父节点需要被他的父节点监控;所以他是未被监控0); 3.子节点有一个状态是2,则父节点返回 1 (因为子节点有一个是有摄像头的所以 父节点是被监控了的) 最后。如果根节点的左右子节点都是1 则他是0 需要一个摄像头res++;
代码
/**
* @param {TreeNode} root
* @return {number}
*/
var minCameraCover = function(root) {
let res=0;
if (dfs(root) == 0) {
res++;
}
// 根据子节点的状态返回父节点的状态;
function dfs(node) {
if (node == null) return 1;
let left=dfs(node.left);
let right=dfs(node.right);
// 1.子节点有一个状态为0,则父节点返回 2 父节点需要一个摄像头 res++(根据贪心思想 由上面的节点监控下面的节点比较省摄像头);
if (left == 0 || right == 0) {
res++;
return 2;
}
// 2.左右2个子节点状态都是1,则父节点返回0 (因为子节点都没有摄像头,所以父节点需要被他的父节点监控;所以他是未被监控0);
if(left==1&&right==1) return 0;
// 3.子节点有一个状态是2,则父节点返回 1 (因为子节点有一个是有摄像头的所以 父节点是被监控了的)
if(left == 2 || right == 2) return 1;
}
return res;
};