题目描述
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
来源,leetcode 每日一题 968. 监控二叉树
例如:
输入:[0,0,null,0,0]输出:1解释:如图所示,一台摄像头足以监控所有节点。
注意
- 给定树的节点数的范围是
[1, 1000]。 -
解题思路
从题目中来看,正面攻破比较困难,但是我们可以反过来想,不外乎几种情况,
- 如果只有一个节点,那么就只要一个监控就可以
- 如果不只有一个节点,那么叶子节点的父节点为监控的策略肯定是更好的
- 如果一个节点初次被访问,如果有父节点,则父节点被设为监控节点是一个好的选择。(自底向上遍历)。
- 题目中出现的节点类型不外乎两种:监控节点和被监控节点。
自底向上遍历,逐步设置被监控节点和监控节点,每设置一个监控节点,则其父节点和子节点都会被监控,设为被监控节点。同时可以被更新为监控节点的类型为初次访问节点和被监控节点。
代码
/*** 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 minCameraCover(TreeNode* root) {if (root == NULL) {return 0;}int answer = 0;if (root->left != NULL) {dfs(root->left, answer, root);}if (root->right != NULL) {dfs(root->right, answer, root);}if (root->val == 0) {answer += 1;}return answer;}void dfs(TreeNode* root, int& answer, TreeNode* parent) {if (root->left != NULL) {dfs(root->left, answer, root);}if (root->right != NULL) {dfs(root->right, answer, root);}if (root->val == 0) {root->val = 2;parent->val = 1;answer+=1;} else if (root->val == 0 && parent->val == 1) {root->val = 2;} else if (root->val == 1 && parent->val == 0) {parent->val = 2;}}};
