📜  监控二叉树所有节点所需的最少摄像头数量(1)

📅  最后修改于: 2023-12-03 15:11:21.922000             🧑  作者: Mango

监控二叉树所有节点所需的最少摄像头数量

问题背景

在监控二叉树(每个节点有左右子节点或者为叶子节点)的所有节点的情况下,需要安装一定数量的摄像头,设计一个算法,使得摄像头数量最少。

思路分析
  1. 根据题目,可以将问题分为三种情况:节点是叶子节点,节点只有一个孩子,节点有两个孩子。设节点 n 需要被监控。
  2. 如果节点 n 是叶子节点,只要在其父节点安装一个摄像头即可。
  3. 如果节点 n 有一个孩子,则需要安装一个摄像头在该节点的父节点上。
  4. 如果节点 n 有两个孩子,则需要在左右子节点的父节点上安装摄像头。因为对于任意一个节点,如果它的左右子树都被监控,那么它就可以被摄像头监控到。
  5. 递归处理子节点。
  6. 设计完算法后,实现函数功能。
代码实现
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def __init__(self):
        self.count = 0

    def minCameraCover(self, root: TreeNode) -> int:
        # 对根节点进行监控
        if not root:
            return 0
        if not root.left and not root.right:
            return 1
        self.count = 0
        if not root.left:
            # 左子树为空,必须在根节点放置摄像头
            self.count += 1
            self.helper(root.right)
        elif not root.right:
            # 右子树为空,必须在根节点放置摄像头
            self.count += 1
            self.helper(root.left)
        else:
            # 左右子树都不为空
            self.helper(root)
        return self.count

    def helper(self, root: TreeNode):
        if not root:
            return
        if not root.left and not root.right:
            return
        if not root.left:
            # 左子树为空,必须在右孩子节点放置摄像头
            self.count += 1
            self.helper(root.right.left)
            self.helper(root.right.right)
        elif not root.right:
            # 右子树为空,必须在左孩子节点放置摄像头
            self.count += 1
            self.helper(root.left.left)
            self.helper(root.left.right)
        else:
            # 左右子树都不为空
            self.helper(root.left.left)
            self.helper(root.left.right)
            self.helper(root.right.left)
            self.helper(root.right.right)
复杂度分析
  1. 时间复杂度:$O(n)$,遍历每个节点。
  2. 空间复杂度:$O(h)$,函数调用栈的深度为树的高度$h$。