leetcode-968:监控二叉树

简介: leetcode-968:监控二叉树

题目

题目链接

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

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

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

示例 1:

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

示例 2:

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

解题

方法一:贪心

参考链接

这是很重要的一个线索,摄像头可以覆盖上中下三层,如果把摄像头放在叶子节点上,就浪费的一层的覆盖。

所以把摄像头放在叶子节点的父节点位置,才能充分利用摄像头的覆盖面积。

那么有同学可能问了,为什么不从头结点开始看起呢,为啥要从叶子节点看呢?

因为头结点放不放摄像头也就省下一个摄像头, 叶子节点放不放摄像头省下了的摄像头数量是指数阶别的。

所以我们要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!

使用后续遍历,这样可以根据左右节点推断出该节点。

0代表该节点 无摄像头、无覆盖

1代表该节点 有摄像头、有覆盖

2代表该节点 无摄像头、有覆盖

class Solution {
public:
    int res;
    int traversal(TreeNode* cur){
        if(cur==nullptr) return 2;
        int left=traversal(cur->left);
        int right=traversal(cur->right);
        if(left==2&&right==2) return 0;//左右节点都有覆盖,那么让该节点无摄像头
        if(left==0||right==0){  //如果左右节点有一个无覆盖,就要让该节点放摄像头
            res++;
            return 1;
        }
        if(left==1||right==1) return 2; //如果有有一个有摄像头,那么该节点表示覆盖
        return -1;//不会到达这一步
    }
    int minCameraCover(TreeNode* root) {
        res=0;
        if(traversal(root)==0) res++;
        return res;
    }
};

精简一下

// 版本二
class Solution {
private:
    int result;
    int traversal(TreeNode* cur) {
        if (cur == NULL) return 2;
        int left = traversal(cur->left);    // 左
        int right = traversal(cur->right);  // 右
        if (left == 2 && right == 2) return 0;
        else if (left == 0 || right == 0) {
            result++;
            return 1;
        } else return 2;
    }
public:
    int minCameraCover(TreeNode* root) {
        result = 0;
        if (traversal(root) == 0) { // root 无覆盖
            result++;
        }
        return result;
    }
};

更加规范的写法

enum STAT{
    Camera,
    Cover,
    NoCover
 };
class Solution {
public:
    int res;
    STAT dfs(TreeNode* cur){
        if(cur==nullptr) return Cover;
        STAT left=dfs(cur->left);
        STAT right=dfs(cur->right);
        if(left==Cover&&right==Cover) return NoCover;
        else if(left==NoCover||right==NoCover){
            res++;
            return Camera;
        }
        else return Cover;
    }
    int minCameraCover(TreeNode* root) {
        res=0;
        if(dfs(root)==NoCover) res++;
        return res;
    }
};


相关文章
|
7小时前
leetcode代码记录(二叉树的所有路径
leetcode代码记录(二叉树的所有路径
10 0
|
7小时前
leetcode代码记录(对称二叉树 中序遍历+回文串 为什么不行
leetcode代码记录(对称二叉树 中序遍历+回文串 为什么不行
8 0
|
7小时前
leetcode代码记录(二叉树的最小深度
leetcode代码记录(二叉树的最小深度
9 0
|
7小时前
leetcode代码记录(二叉树的最大深度
leetcode代码记录(二叉树的最大深度
8 0
|
7小时前
leetcode代码记录(翻转二叉树
leetcode代码记录(翻转二叉树
7 0
|
7小时前
leetcode代码记录(二叉树的层序遍历
leetcode代码记录(二叉树的层序遍历
11 0
|
7小时前
|
算法
leetcode代码记录(二叉树递归遍历
leetcode代码记录(二叉树递归遍历
8 0
|
7小时前
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
|
7小时前
|
算法 API DataX
二叉树(下)+Leetcode每日一题——“数据结构与算法”“对称二叉树”“另一棵树的子树”“二叉树的前中后序遍历”
二叉树(下)+Leetcode每日一题——“数据结构与算法”“对称二叉树”“另一棵树的子树”“二叉树的前中后序遍历”
|
7小时前
|
算法 DataX
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”