968.监控二叉树
困难程度,二叉树题型
题目描述:给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。
分析
首先分析解题方法,我的理解是,类似高考之前咱们的刷题,每一种题型应该是由类似固定的解题思路,也就是模板套路;这里是关于二叉树的题目,一想到二叉树,我们首先应该想到的是递归解题,然后应该想到的是如何进行树的遍历————先序,中序还是后续?根据不同的题目,应该是采用不同的遍历方式进行递归调用。本题难度为hard,难点就在于,在二叉树的基础上,这里面要考虑状态的变化,有点像动态规划的状态转移方程,因为我们可以思考一下,每一节点的状态主要有三种状态:被覆盖(2),没有被覆盖(0),以及放监视器(1).不同状态用不同的数字进行标注。根据题目意思,要尽可能的使监视器的数目最小,那么监视器应该尽量放到每一次遍历时叶子节点的父节点上去,所以遍历方式我们采用后续遍历,根据叶子节点的状态,我们再决定父节点的状态。
接下来是最难的一部,我们需要考虑所有叶子节点可能的情况,然后推算出父节点的状态。这里面主要有以下几种情况:
- 左右子节点被覆盖
- 这种情况下,父节点不用装监视器,状态为未被覆盖; - 左右节点至少一个未覆盖
- 因为要使所有节点覆盖,为了使叶子节点被覆盖,父节点必须装监视器; - 左右节点至少一个装了监视器(另一个是被覆盖的,未覆盖在上一种情况被包含)
- 这种情况,父节点肯定是被覆盖
根据以上分析,下面的代码可以很好的被理解了
/**
* 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 {
int result = 0;
public:
int minCameraCover(TreeNode* root) {
if(travel(root) == 0)
result++;
return result;
}
// travel函数遍历以当前节点为根节点时,当前节点的状态
int travel(TreeNode* cur){
if(cur == NULL) return 2;
int left = travel(cur->left);
int right = travel(cur->right);
if((left==2) && (right==2)){
return 0;
}
if((left==0) || (right==0)){
result++;
return 1;
}
if((left==1)||(right==1)){
return 2;
}
return -1;
}
};
这里面注意的是,root的状态,最后要判断一下,如果是0,得另外加上监视器

浙公网安备 33010602011771号