968.监控二叉树*
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
思路
题解给出了一种贪心方法,一种状态转移方法,当前节点的状态要依靠左右子节点的状态来定。遇到这种问题还是尽可能穷举一下有几种状态变化。
题解设定0为监控无覆盖,1为监控,2为监控有覆盖。那么根据左右节点的这三种状态,递归判断当前节点的状态:全为2,返0;有一个为1,返2;有一个为0,返1。
还需注意一点是,头结点因树的结构问题出现无法被监控的情况,最后结果需要根据其是否被监控来决定是否+1.
代码
int count = 0;
public int minCameraCover(TreeNode root) {
//while先序遍历,记录当前节点的父节点f及其父节点的父节点gf,找到最左下的叶子节点,将本身f和gf的val标1,判断f是否存在right节点,若存在将其右节点的val标1.count技计数加1.继续遍历,若遇叶子节点,重复上述操作。
if (root == null) return 0;
decode(root);
if (root.val==0) count++;
return count;
}
//后序遍历
public int decode(TreeNode node){
if (node==null) return 2;
int left =decode(node.left);
int right =decode(node.right);
//均处于2有覆盖状态
if (left==2 && right==2){
node.val=0;
return 0;
}else if (left==0 || right==0){
node.val=1;
count++;
return 1;
}else if (left==1 || right==1){
node.val=2;
return 2;
}
return 0;
}