题目链接:
https://leetcode-cn.com/problems/binary-tree-cameras/
难度:困难
968. 监控二叉树
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
提示:
给定树的节点数的范围是 [1, 1000]。
每个节点的值都是 0。
好难 不会 。。。。 这貌似是做过的递归题中最难的一个 不过还是比较好理解的 (做个坐标 题解)
分析:
对于每一个root(根节点) 有两种情况:第一个是自身有监控 左右子树各自保证覆盖
第二个是 不保证自身有监控 左右子树保证自身覆盖的同时 其中一个必须保证根节点被检测到 (覆盖 想当于监听)
这对应了三种状态:
- a:root自身放置摄像头的情况下 覆盖整棵树需要的摄像头数量
- b:覆盖整棵树的摄像头的数量 无论root是否放置摄像头
- c:覆盖两颗子树所需要的摄像头的数量 无论root是否被覆盖
若左右子树的情况为 (la,lb,lc) (ra,rb,rc)
a=lc+rc+1
b=min(a,min(lb+ra,la+rb))
c=min(a,lb+rb) (root 是否放置摄像头 两种情况)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
struct Status{
int a,b,c;
};
class Solution {
public:
Status dfs(TreeNode* root){
if(!root){
return {INT_MAX/2,0,0};
}
auto [la,lb,lc]=dfs(root->left);
auto [ra,rb,rc]=dfs(root->right);
int a=lc+rc+1;
int b=min(a,min(la+rb,ra+lb));
int c=min(a,lb+rb);
return {a,b,c};
}
int minCameraCover(TreeNode* root) {
auto [a,b,c]=dfs(root);
return b;
}
};
emmm。。。 下次碰到可能还是不会 有点难想到