题目:
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/*
1、每个节点可能具有的状态,分别对应一个数字:
* 0:该节点无无摄像头且无覆盖
* 1:该节点有摄像头
* 2:该节点无摄像头且有覆盖
2、对于单个节点可能有的情况可分为以下四类:
* 情况1:左右孩子都有覆盖,那么此时该节点应该就是无覆盖的状态了,也就是状态0
* 情况2:左右孩子至少有一个无覆盖的情况,则该节点应该放置一个摄像头,也就是状态1
* left == 0 && right == 0
* left == 1 && right == 0
* left == 2 && right == 0
* left == 0 && right == 1
* left == 0 && right == 2
* 情况3:左右孩子至少有一个有摄像头,那么本节点无需放置摄像头,且已经是被覆盖的状态,也就是状态2
* left == 1 && right == 1
* left == 1 && right == 2
* left == 2 && right == 1
* 情况4:头结点没有覆盖
* 以上三种情况都不涵盖对头结点的特殊处理,当递归结束后,头结点还有可能是 无覆盖的状态,
* 因此递归结束后,需要单独判断一下头结点,如果没有被覆盖,则 result++;
*/
class Solution {
// 难点:要搞清楚 三种状态,以及4种情况
private:
int result;
int travel(TreeNode* cur)
{
// 终止条件,节点为空表示 第 0 种状态
if(cur == nullptr)
{
return 2;
}
// 后序遍历 左 右 中
int left = travel(cur->left);
int right = travel(cur->right);
if(left == 2 && right == 2) return 0;
else if(left == 0 || right == 0)
{
result++;
return 1;
}
// 注释掉的这两句跟 else 一样的意思,等价可替换
// if(left == 1 || right == 1) return 2;
// return -1;
else
{
return 2;
}
}
public:
int minCameraCover(TreeNode* root)
{
result = 0;
if(travel(root) == 0)
{
result++;
}
return result;
}
};