Leetcode刷题笔记 968. 监控二叉树

968. 监控二叉树

知识点:二叉树、递归、状态统计
时间:2020年9月22日
题目链接:https://leetcode-cn.com/problems/binary-tree-cameras/

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

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

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

示例1
输入

在这里插入图片描述
[0,0,null,0,0]

输出
1
解释
如图所示,一台摄像头足以监控所有节点。

示例2
输入

在这里插入图片描述
[0,0,null,0,null,0,null,null,0]

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

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

解法

  1. 对于每个节点有三个状态: 0没有被监控 ,1被监控 ,2放置相机
  2. 采用后续遍历去求解,自底向上,先考虑左右儿子节点,再是本身节点
  3. 我们希望放的相机越少越好,叶节点放相机不合算,放在该节点的父亲节点就可,所以递归到空节点返回被监控 为1
    4.具体的情况
    1. 左右儿子 都被监控到了 该节点肯定没有被监控 为0 但放不放相机不一定(不返回2)
    2. 左右儿子 至少有一个没被监控到 该节点必须放置相机 为2
    3. 左右儿子 至少有一个有相机 该节点状态为被监控 为1
    4. 遍历到最后如果头节点没被覆盖 需要放置

代码

#include <stdio.h>
#include <iostream>
using namespace std;
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    int ans;
    int traversal(TreeNode* cur) {
        //空节点返回被监测
        if(cur==nullptr) return 1;
        //后续遍历
        int left = traversal(cur->left);
        int right = traversal(cur->right);
        //左右节点都被监测
        if(left==1 && right==1)return 0;
        //左右节点中有一个没被监测,则该节点必须放相机,状态为2
        if(left==0 || right==0){ans++; return 2;}
        //左右节点中有一个被放置相机,则该节点状态为1
        if(left==2 || right ==2)return 1;
        return -1;
    }
    int minCameraCover(TreeNode* root) {
        //最后根节点为未被监测时,需要放置
        ans = 0;
        if(traversal(root)==0)
            ans ++;
        return ans;
    }
};
int main()
{
    Solution s;
    TreeNode node1(1); TreeNode node2(1); TreeNode node3(1);
    TreeNode node4(1); TreeNode node5(1); TreeNode node6(1);
    node1.left = &node2; node1.right=&node3;
    node2.left = &node4; node2.right =&node5;
    node5.right = &node6;
    int ans = s.minCameraCover(&node1);
    cout<<ans<<endl;
    return 0;
}

今天也是爱zz的一天哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值