贪心 Leetcode 968 监控二叉树

监控二叉树

Leetcode 968

学习记录自代码随想录

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

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

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

要点:1.想到优先覆盖叶子节点,即让叶子节点的父节点有摄像头;

2.想到每个节点有三种状态0-无覆盖,1-摄像头,2-有覆盖;

3.优先覆盖叶子节点,需要从下到上遍历,用后序遍历左右中;

4.四种情况:a.左右节点都有覆盖,则中间节点为无覆盖;b.左右节点至少一个无覆盖,则中间节点为摄像头1;c.左右节点至少一个摄像头,则中间节点为有覆盖;d.最后判断根节点是否为无覆盖,若是,还要添加一个摄像头到根节点;

5.首先是要想到贪心的思路,然后就是遍历和状态推导,此题较难,很难直接想到。

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int result;
    int traversal(TreeNode* cur){
        //节点状态:0-无覆盖,1-摄像头,2-有覆盖
        // 空节点:为有覆盖2, 因为尽量保证叶子节点的父节点有摄像头,所以空节点只能为有覆盖2
        if(cur == nullptr) return 2;

        // 尽量保证叶子节点被覆盖,即叶子节点父节点要有摄像头,所以遍历为后序遍历
        int left = traversal(cur->left);
        int right = traversal(cur->right);

        // 1.左右节点均为有覆盖2,则中间节点为无覆盖0
        if(left == 2 && right == 2) return 0;
        // 2.左右节点至少一个为无覆盖0,则中间节点为摄像头1
        if(left == 0 || right == 0){
            result++;
            return 1;
        }
        // 3.左右节点至少一个有摄像头,则中间节点为有覆盖2
        if(left == 1 || right == 1) return 2;

        return -1;  // 上述代码未使用else,所以逻辑不会走到这里,仅作形式此处
    }
    int minCameraCover(TreeNode* root) {
        // 局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
        result = 0;
        // 4.如果最后根节点无覆盖,则需要多一个摄像头
        if(traversal(root) == 0){
            result++;
        }
        return result;
    }
};
相关推荐
木子.李3474 小时前
排序算法总结(C++)
c++·算法·排序算法
闪电麦坤955 小时前
数据结构:递归的种类(Types of Recursion)
数据结构·算法
互联网杂货铺6 小时前
完美搭建appium自动化环境
自动化测试·软件测试·python·测试工具·职场和发展·appium·测试用例
Gyoku Mint6 小时前
机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你
人工智能·python·算法·机器学习·pandas·ai编程·matplotlib
纪元A梦6 小时前
分布式拜占庭容错算法——PBFT算法深度解析
java·分布式·算法
px不是xp6 小时前
山东大学算法设计与分析复习笔记
笔记·算法·贪心算法·动态规划·图搜索算法
枫景Maple7 小时前
LeetCode 2297. 跳跃游戏 VIII(中等)
算法·leetcode
鑫鑫向栄7 小时前
[蓝桥杯]修改数组
数据结构·c++·算法·蓝桥杯·动态规划
鑫鑫向栄7 小时前
[蓝桥杯]带分数
数据结构·c++·算法·职场和发展·蓝桥杯