You are given the root
of a binary tree. We install cameras on the tree nodes where each camera at a node can monitor its parent, itself, and its immediate children.
Return the minimum number of cameras needed to monitor all nodes of the tree.
Example 1:
Input: root = [0,0,null,0,0] Output: 1 Explanation: One camera is enough to monitor all nodes if placed as shown.
Example 2:
Input: root = [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.
Constraints:
- The number of nodes in the tree is in the range
[1, 1000]
. Node.val == 0
监控二叉树。
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
提示:
给定树的节点数的范围是 [1, 1000]。
每个节点的值都是 0。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-cameras
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题的思路是后序遍历 + 贪心。因为每个摄像头可以监控自己 + 父节点 + 自己的左右孩子,这就是四个节点。前序遍历应该是行不通的,因为我们不知道这棵树到底有几层,而且如果按照前序遍历做,不能很好地利用到可以监控父节点这个条件。
这道题为什么是 HARD 我觉得是因为后序遍历不知道往父节点传什么信息才能很好地表达当前节点是否需要被监控,是如何被监控的信息。我这里提供一个思路,
// 0 - 这个结点待覆盖 // 1 - 这个结点已经覆盖 // 2 - 这个结点上需要安装相机后序遍历的 helper 函数里面,
- 如果当前节点为空,则说明不需要被覆盖 - 换言之当前节点已经被覆盖了,返回 1
- 对于当前节点的左右孩子,如果他们之中有一个没有被覆盖,那么就要在当前节点装摄像头以确保他们被覆盖,返回 2,同时 res++
- 对于当前节点的左右孩子,如果他们都被覆盖了,则当前节点不需要装摄像头,返回 0,注意当前摄像头是可以通过在其父节点安装摄像头以覆盖的,所以即使当前节点未被覆盖也没关系
- 对于当前节点的左右孩子起码有一个有camera了,说明当前节点可以被覆盖,则返回 1
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 int res = 0; 18 19 public int minCameraCover(TreeNode root) { 20 if (helper(root) == 0) { 21 res++; 22 } 23 return res; 24 } 25 26 private int helper(TreeNode root) { 27 if (root == null) { 28 return 1; 29 } 30 int left = helper(root.left); 31 int right = helper(root.right); 32 // 左右孩子有一个未覆盖,就要在当前节点装camera 33 if (left == 0 || right == 0) { 34 res++; 35 return 2; 36 } 37 // 左右孩子都被覆盖了,则当前节点不需要装camera 38 if (left == 1 && right == 1) { 39 return 0; 40 } 41 // 左右孩子起码有一个有camera了,说明当前节点可以被覆盖 42 if (left + right >= 3) { 43 return 1; 44 } 45 return -1; 46 } 47 } 48 // 0 - 这个结点待覆盖 49 // 1 - 这个结点已经覆盖 50 // 2 - 这个结点上需要安装相机
LeetCode 题目总结