(51)~968. 监控二叉树-迷糊

116 阅读2分钟

这道题,看了很多解析,都看的头大,特别官方给出的解体思路,最后从js解体思路中找到了一个,稍微好理解点儿的,吵了一遍

/*
 * @lc app=leetcode.cn id=968 lang=javascript
 *
 * [968] 监控二叉树
 */

// @lc code=start
/**
 * 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)
 * }
 * 
 * 
 * 解题思路 -- 贪心算法
第一步:确定节点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;
	// 跟节点未被监视 则res ++
	if (dfs(root) === 0) {
		res++;
	}

	// 定义dfs 后序遍历 从下往上照
	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;

};
// @lc code=end


力扣本题传送门