【路飞】算法与数据结构-监控二叉树 

155 阅读2分钟

LeetCode:地址

题目要求

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

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

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

示例 1:

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

示例 2:

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

提示:

  1. 给定树的节点数的范围是 [1, 1000]
  2. 每个节点的值都是 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;
};