给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

 

示例 1:

 

输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:

 

输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。

提示:

给定树的节点数的范围是 [1, 1000]。
每个节点的值都是 0。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-cameras
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

今天给我推了一道不会的题,看题解才勉强明白吧,记录一下。

记录三个状态一层一层往上状态转移,a表示当前节点需要加摄像头的前提下它往下的节点都被监控到需要的最少摄像头总数,b表示去掉a要求的前提后需要的最少摄像头总数,c表示不管当前节点但是要保证下面的节点都被监控到需要的最少摄像头总数。这样一来对于a而言当前节点加了摄像头,他的左右儿子都可以被监控到了,只需要解决左右儿子各自的子树被监控到就可以了,所以a = lc + rc;对于c而言,只需要考虑左右儿子是否被监控到就行了,lb + rb显然是满足的,a也是满足的,两者取最小值;对于b,有两种情况,就是当前节点加不加摄像头,加的话就是a,不加的话他的左右儿子至少有一个得加摄像头,也就是从la + rb和lb + ra中取最小值,再跟a比较取最小值。

 

代码:

/**
 * 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 c = 0,s[1001][3] = {0};
    int minCameraCover(TreeNode* root) {
        if(root == NULL) return 0;
        minCameraCover(root -> left);
        minCameraCover(root -> right);
        if(root -> val == 0) root -> val = ++ c;
        s[root -> val][0] = 1;
        int a = 0,b = 0;
        if(root -> left) {
            s[root -> val][0] += s[root -> left -> val][2];
            s[root -> val][2] += s[root -> left -> val][1];
            a += s[root -> left -> val][0];
            b += s[root -> left -> val][1];
        }
        else a = 0x3f3f3f3f;
        if(root -> right) {
            s[root -> val][0] += s[root -> right -> val][2];
            s[root -> val][2] += s[root -> right -> val][1];
            b += s[root -> right -> val][0];
            a += s[root -> right -> val][1];
        }
        else b = 0x3f3f3f3f;
        s[root -> val][1] = min(s[root -> val][0],min(a,b));
        s[root -> val][2] = min(s[root -> val][2],s[root -> val][0]);
        return s[root -> val][1];
    }
};