968. 监控二叉树
问题描述
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
提示:
- 给定树的节点数的范围是
[1, 1000]
。 - 每个节点的值都是 0。
解题思路与代码实现
贪心策略:尽可能减少摄像头放置,不用从叶子节点开始放,间隔放置
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int res = 0; // 计数器
public int minCameraCover(TreeNode root) {
if (travel(root) == -1) {
res++;
}
return res;
}
/**
* 返回值有3种,含义如下:
* -1:该节点未被其他摄像头覆盖;
* 0:该节点有摄像头;
* 1:该节点被其他摄像头覆盖
*/
private int travel(TreeNode root) {
// 空节点认为被覆盖,以尽可能减少摄像头数量
if (root == null)
return 1;
// 左右子树递归
int leftVal = travel(root.left);
int rightVal = travel(root.right);
if (leftVal == 1 && rightVal == 1) { // 左右孩子均被其他摄像头覆盖
// (1,1)
return -1;
}
if (leftVal == -1 || rightVal == -1) { // 左右孩子均未被其他摄像头覆盖
// (-1,-1)、(-1,0)、(-1,1)、(0,-1)、(1,-1)
res++;
return 0;
} else { // 左右孩子至少有一个有摄像头
// (0,1)、(1,0)、(0,0)
return 1;
}
}
}
踩坑点
无