算法学习:968.监控二叉树

监控二叉树

题目链接:力扣题目链接
难度:困难
给定一个二叉树,我们在树的节点上安装摄像头。


节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。


计算监控树的所有节点所需的最小摄像头数量。


示例

转载力扣官网
输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。

思路

二叉树节点定义

public class TreeNode{
	int val;
	TreeNode left;
	TreeNode right;
	TreeNode(){}
	TreeNode(int val){this.val = val}
	TreeNode(int val,TreeNode left,TreeNode right){
		this.val = val;
		this.left = left;
		this.right = right;
	}
}

思路

从题目示例可以看出,所有的摄像头都没有放在叶子节点,摄像头可以覆盖上下中三层,如果放在叶子节点,就浪费了一层的覆盖,所以把摄像头放在叶子节点的父节点位置,才能充分利用摄像头的覆盖面积。要从下往上看,让叶子节点的父节点安装摄像头,所用摄像头最少。在二叉树中从低向上导,可以使用后序遍历也就是左右中的顺序,这样就可以在回溯的过程中从下到上进行推导了。
每个节点都有三种状态,情况一,该节点无覆盖,情况二,该节点有摄像头,情况三,该节点有覆盖。可以分别用三个数字表示三种情况的状态,0表示该节点无覆盖,1表示该节点有摄像头,2表示该节点有覆盖。空节点是有覆盖的,所以递归遇见了空节点,应该返回2。

贪心法

class Solution{
	private int result = 0;
	public int minCameraCover(TreeNode root) {
		// root 无覆盖
		if(travl(root) == 0)	result++;
		return result;
	}
	private int travl(TreeNode root){
		// 空节点,该节点有覆盖
		if(root == null)	return 2;
		int left = travl(root.left);	// 左
		int right = travl(root.right);	// 右
		// left == 0 && right == 0 左右节无覆盖
        // left == 1 && right == 0 左节点有摄像头,右节点无覆盖
        // left == 0 && right == 1 左节点无覆盖,右节点摄像头
        // left == 0 && right == 2 左节点无覆盖,右节点覆盖
        // left == 2 && right == 0 左节点覆盖,右节点无覆盖
		if(left == 0 || right == 0){
			result++;
			return 1;
		}
		// 左右节点都有覆盖
		if(left == 2 && right == 2){
			return 0;	
		}
		// left == 1 && right == 2 左节点有摄像头,右节点有覆盖
        // left == 2 && right == 1 左节点有覆盖,右节点有摄像头
        // left == 1 && right == 1 左右节点都有摄像头
        // 其他情况前段代码均已覆盖
		if(left == 1 || right == 1){
			return 2;
		}
		return -1;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 统计二叉树的叶结点个数: 算法分析:采用递归算法,若当前结点为空,则返回0;若当前结点没有左右子树,则返回1;否则返回左右子树叶结点个数之和。 时间复杂度:O(n),其中n为二叉树结点个数。 数据分析:该算法的时间复杂度较低,适用于结点数量较少的二叉树。但在结点数量较多的情况下,递归调用次数增多,可能会导致栈溢出。 2. 判别两棵树是否相等: 算法分析:采用递归算法,若两棵树均为空,则返回true;若两棵树均不为空且根结点的值相等,则分别判断左右子树是否相等,若均相等则返回true,否则返回false。 时间复杂度:O(n),其中n为二叉树结点个数。 数据分析:该算法的时间复杂度较低,适用于结点数量较少的二叉树。但在结点数量较多的情况下,递归调用次数增多,可能会导致栈溢出。 3. 交换二叉树每个结点的左孩子和右孩子: 算法分析:采用递归算法,若当前结点为空,则返回;否则交换左右子树,分别递归处理左右子树。 时间复杂度:O(n),其中n为二叉树结点个数。 数据分析:该算法的时间复杂度较低,适用于结点数量较少的二叉树。但在结点数量较多的情况下,递归调用次数增多,可能会导致栈溢出。 4. 设计二叉树的双序遍历算法算法分析:采用栈来实现,将根结点入栈,然后循环执行以下操作:若栈不为空,则取出栈顶元素并输出;若该结点有右子树,则将右子树入栈;若该结点有左子树,则将左子树入栈。 时间复杂度:O(n),其中n为二叉树结点个数。 数据分析:该算法的时间复杂度较低,适用于结点数量较少的二叉树。但在结点数量较多的情况下,栈空间可能会不够用,导致栈溢出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

As_theWind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值