题目描述
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
来源,leetcode 每日一题 968. 监控二叉树
例如:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
注意
- 给定树的节点数的范围是
[1, 1000]
。 -
解题思路
从题目中来看,正面攻破比较困难,但是我们可以反过来想,不外乎几种情况,
- 如果只有一个节点,那么就只要一个监控就可以
- 如果不只有一个节点,那么叶子节点的父节点为监控的策略肯定是更好的
- 如果一个节点初次被访问,如果有父节点,则父节点被设为监控节点是一个好的选择。(自底向上遍历)。
- 题目中出现的节点类型不外乎两种:监控节点和被监控节点。
自底向上遍历,逐步设置被监控节点和监控节点,每设置一个监控节点,则其父节点和子节点都会被监控,设为被监控节点。同时可以被更新为监控节点的类型为初次访问节点和被监控节点。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int minCameraCover(TreeNode* root) {
if (root == NULL) {
return 0;
}
int answer = 0;
if (root->left != NULL) {
dfs(root->left, answer, root);
}
if (root->right != NULL) {
dfs(root->right, answer, root);
}
if (root->val == 0) {
answer += 1;
}
return answer;
}
void dfs(TreeNode* root, int& answer, TreeNode* parent) {
if (root->left != NULL) {
dfs(root->left, answer, root);
}
if (root->right != NULL) {
dfs(root->right, answer, root);
}
if (root->val == 0) {
root->val = 2;
parent->val = 1;
answer+=1;
} else if (root->val == 0 && parent->val == 1) {
root->val = 2;
} else if (root->val == 1 && parent->val == 0) {
parent->val = 2;
}
}
};