Given a binary tree, we install cameras on the nodes of the tree.
Each camera at a node can monitor its parent, itself, and its immediate children.
Calculate the minimum number of cameras needed to monitor all nodes of the tree.
Example 1:
Input: [0,0,null,0,0] Output: 1 Explanation: One camera is enough to monitor all nodes if placed as shown.
Example 2:
Input: [0,0,null,0,null,0,null,null,0] Output: 2 Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.
Note:
[1, 1000]
.
题目理解:
给定一棵二叉树,在二叉树中放置若干个‘照相机’,使得任意一个节点都被‘照相机’覆盖,一个照相机可以覆盖一跳之内的全部节点,问最少使用多少照相机
解题思路:
使用递归方法从底层向上解决这个问题。
对于任意一棵子树,根节点是root,定义三种状态:
a:root没有被覆盖,但是root的子节点全部被覆盖到了
b:root没有放置相机,但是root和root的全部子节点都被覆盖到了
c:root放置了相机,并且root的全部子节点都被覆盖到了
对于空节点,我们定义(a,b,c)=(0,0,1)
对于非空节点,先处理其左右子节点,得到左右子节点的信息l和r则:
a = min(l.b, l.c) + min(r.b, r.c); 一般情况下,不覆盖root用的照相机少一些,但是如果用更少的相机反而可以覆盖root,那更好
b = min(min(l.b, l.c) + r.c, l.c + min(r.b, r.c)); 如果要覆盖root,那么root的两个子节点一定要有一个有照相机
c = min(l.a, l.b, l.c) + min(r.a, r.b, r.c) + 1; 如果root有照相机,那么root的子节点处于任意一个状态都可以
最后返回根节点的b,c中间较小的一个
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] dfs(TreeNode root){
if(root == null)
return new int[]{0, 0, 1};
int[] l, r;
l = dfs(root.left);
r = dfs(root.right);
int a = Math.min(l[1], l[2]) + Math.min(r[1], r[2]);
int b = Math.min(Math.min(l[1], l[2]) + r[2], l[2] + Math.min(r[1], r[2]));
int c = Math.min(l[0], Math.min(l[1], l[2])) + Math.min(r[0], Math.min(r[1], r[2])) + 1;
return new int[]{a, b, c};
}
public int minCameraCover(TreeNode root) {
int[] res = dfs(root);
return Math.min(res[1], res[2]);
}
}