算法题之监控二叉树问题
问题描述
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。
示例 2:
输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
题解
代码实现
package com.bingym.datasource.binarytree.monitornode;
import sun.reflect.generics.tree.Tree;
public class MonitorBinaryTreeNode {
/*
* 给定一个二叉树,监控树的节点(父节点,自身,子节点)需要最少的摄像头数量
* */
//static int count = 0;
public static void main(String[] args) {
//[0,0,null,0,null,0,null,null,0]
TreeNode node1 = new TreeNode(0);
TreeNode node2 = new TreeNode(0);
TreeNode node3 = null;
TreeNode node4 = new TreeNode(0);
TreeNode node5 = null;
TreeNode node6 = new TreeNode(0);
TreeNode node7 = null;
TreeNode node8 = null;
TreeNode node9 = new TreeNode(0);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node4.left = node6;
node4.right = node7;
node6.left = node8;
node6.right = node9;
MonitorBinaryTreeNode solution = new MonitorBinaryTreeNode();
int res = solution.minCameraCover(node1);
System.out.println("监控树的节点(父节点,自身,子节点)需要最少的摄像头数量为:" + res);
}
int res = 0;//定义存放最少摄像头的结果变量res
public int minCameraCover(TreeNode root) {
// 节点值0:未监视,1:已监视,2:摄像头
if (dfs(root) == 0) {//表示若该二叉树只有root节点一个节点,则左子树和右子树均为1状态,返回dfs(root)为0,此时需要将res加1,即本身装置一个摄像头,监控自己
res++;
}
return res;
}
private int dfs(TreeNode root) {
if (root == null) {//若该节点为null,则直接返回1
return 1;
}
int left = dfs(root.left);
int right = dfs(root.right);
// 有子节点未被监视,需装摄像头
if (left == 0 || right == 0) {//该节点为父节点,有左子树和右子树
res++;
return 2;
}
// 子节点均被监视,当前节点无需设置摄像头或置为被监视[即该节点为叶子节点,左子节点和右子节点均为null]
if (left == 1 && right == 1) {
return 0;
}
// 子节点至少有一个摄像头,设为被监视,即该节点存在左子树或者右子树
if (left + right >= 3) {
return 1;
}
//保证该方法的合法性:不会满足此种情况
return -1;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}