给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
LeetCode题目链接:https://leetcode-cn.com/problems/binary-tree-cameras/
从题目中知道,我们需要求得最小摄像头数量
那么怎么样去保证 最小 呢
我们来用一个节点的不需安装摄像头的情况列举一下
- 当此节点的左右子节点,一个节点为已监视状态,一个节点为已安装状态,不需安装摄像头
- 当此节点的左右子节点均为已安装状态,不需安装摄像头
- 当此节点的左右子节点均为空,不需安装摄像头
- 当此节点的左右子节点均为已监视状态,不需安装摄像头
对于3、4情况下,不需安装摄像头的原因就是,可以交给父节点去安装,以达到监视此节点的效果
(这里其实有一些贪心思想)
但是这3、4情况有一个特例,那就是当此节点为根节点的时候,这两种情况仍然需要安装摄像头
看下图
为了便于记录
将 0标记为未监视
1标记为已监视
2标记为已安装
图1:
图2:
我们再来将一个节点的需要安装摄像头的情况列举一下
- 当此节点的左右子节点其中一个为未监视,需要安装摄像头
所有情况已经列举出来,那么就显而易见了,将其转化为代码(注释中已将各个情况处理所在标出)
代码如下
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int count = 0;
//0未监视 1已监视 2已安装
int dfs(TreeNode* root) {
if (root == NULL)
return -1;
int left = dfs(root->left), right = dfs(root->right);
if (left == -1 && right == -1)return 0; //不需安装情况 3
if (left == 0 || right == 0) //需要安装
{
count++;
return 2;
}
if (left == 2 || right == 2)return 1; //不需安装情况 1、2
return 0; //不需安装情况 4
}
int minCameraCover(TreeNode* root) {
//处理根节点情况
//dfs(root)返回0时
//说明根节点无法被监视到
//因此需要在根节点处加一个摄像头
return (dfs(root) == 0) ? count + 1 : count;
}
};