题目链接
题解
题意
emm如题啦~
思路
我们将“覆盖”定义为该节点可以被监控到。
设节点有三种状态:
- 未被覆盖;
- 有摄像头;
- 已被覆盖。
为了使用最少的摄像头,监控尽可能多的节点,我们要自下而上地安装摄像头。
为了完成这个操作,我们需要用到后序遍历。
关于返回的状态,我们从叶子节点的子节点——空节点开始推导。
对于一个空节点:
- 如果它的状态为未被覆盖,则其父节点处需要安装摄像头,造成浪费;
- 如果它的状态为有摄像头,则其父节点处状态为已被覆盖,导致摄像头安装在其父节点的父节点(爷爷节点喽~)的父节点处,造成其父节点——叶子节点无法被覆盖;
- 如果它的状态为已被覆盖,则其父节点处状态为未被覆盖,使得摄像头安装在其父节点的父节点处,完美~
最后需要处理一下根节点,如果返回状态为未被覆盖,则最终的结果需要加1。
AC代码
/**
* 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 ans = 0;
int dfs(TreeNode* root) {
if (root == nullptr) {
return 2;
}
int left = dfs(root->left);
int right = dfs(root->right);
// 如果有子节点未被覆盖,则需要安摄像头
if ((left == 0 && right == 0) || (left == 1 && right == 0) || (left == 0 && right == 1) || (left == 0 && right == 2) || (left == 2 && right == 0)) {
ans += 1;
return 1;
}
// 如果子节点可以覆盖此处,则返回已覆盖
if ((left == 1 && right == 2) || (left == 2 && right == 1) || (left == 1 && right == 1)) {
return 2;
}
// 如果子节点已被覆盖,则此处无需摄像头且未被覆盖
if ((left == 2 && right == 2)) {
return 0;
}
return 0;
}
int minCameraCover(TreeNode* root) {
if (dfs(root) == 0) {
ans += 1;
}
return ans;
}
};
后记
啊这是我之前wa了两次的代码,我推啊推的觉得没问题,甚至十分完美,发现错在哪的我宛如智障QAQ
(不过我可以蹲一个只监控子节点的题hhhhhhhhhh
/**
* 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 ans = 0;
bool dfs(TreeNode *root) {
while (root->left != nullptr || root->right != nullptr) {
bool son1 = false, son2 = false;
if (root->left == nullptr || (root->left->left == nullptr && root->left->right == nullptr)) {
son1 = true;
} else {
if (dfs(root->left)) root->left = nullptr;
}
if (root->right == nullptr || (root->right->right == nullptr && root->right->left == nullptr)) {
son2 = true;
} else {
if (dfs(root->right)) root->right = nullptr;
}
if (son1 && son2) {
ans += 1;
return true;
}
}
return false;
}
int minCameraCover(TreeNode* root) {
if (root -> left == nullptr && root -> right == nullptr) return 1;
else if (root == nullptr) return 0;
dfs(root);
return ans;
}
};