题目
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
提示:
- 给定树的节点数的范围是
[1, 1000]
。 -
解题方法
贪心
局部最优:一个相机覆盖面积最大化(在叶子结点的父节点上)。
对于一个节点由三种状态,表述如下:0
:该节点未被监控,需要被监控1
:该节点被监控,不需要提供监控2
:该节点有相机,可以为周围节点提供监控。
该题采用后序遍历的方式,首先遍历左右子树,再根据左右子树的情况判定当前节点是否需要提供摄像头,判定如下:
if(left==0 || right==0)
:当前节点需要提供摄像头给子节点。else if(left==2 || right==2)
:当前节点可以被子节点的摄像头覆盖。else
:当前节点的左右子树均已被监控,需要当前节点的父节点提供监控
时间复杂度O(n)
,空间复杂度O(n)
C++代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
int sum = 0;
public:
int dfs(TreeNode* cur) {
if(!cur) return 1;
int left = dfs(cur->left);
int right = dfs(cur->right);
if(left==0 || right==0) {
sum++;
return 2;
}
else if(left==2 || right==2) return 1;
else return 0;
}
int minCameraCover(TreeNode* root) {
int cur = dfs(root);
if(cur==0) sum++;
return sum;
}
};