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