题目描述
竞赛积分2124题号968
思路
我们给节点划分成三种状态:
- 该节点没有被覆盖(在本题上下文中,称为没有被监控)记为状态0
- 该节点是支配节点(在本题上下文中,称为有摄像头) 记为状态1
- 该节点被覆盖(在本题上下文中,称为被监控)记为状态2
基于“叶子节点的父节点安装摄像头要优于叶子节点本身安装摄像头”的出发点,我们采用自底向上,后序遍历的方法。根据左右儿子节点的状态,推理出本节点的状态。
-
如果左右儿子节点但凡有一个为未覆盖,那么父节点必须安装摄像头。此时答案加一,并且返回父节点的状态:1
-
如果左右节点任意一个为有监控,那么父节点必为被覆盖,直接返回父节点状态:2
-
如果左右节点全为状态2,那么推断当前父节点为未覆盖。但是你不要心急给答案加1说父节点必须装个摄像头,它按道理来说应该是不装摄像头,留给父节点的父节点去装,会更省一点。所以返回父节点的状态:0。
-
特殊情况,如果最终判断根节点的状态为0,此时无人尝试覆盖根节点,无奈,只能特判一下:如果根节点无人覆盖,那么根节点只能特殊装一个摄像头。
代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def minCameraCover(self, root: Optional[TreeNode]) -> int:
ans = 0
def dfs(node) :
nonlocal ans
if not node :
return 2
l_res = dfs(node.left)
r_res = dfs(node.right)
if l_res == 0 or r_res == 0 : # 子节点有无覆盖状态 那么父节点必须有监控
ans += 1
return 1
if l_res == r_res == 2 : # 子节点全为覆盖状态 那么父节点为无覆盖状态
return 0
if l_res == 1 or r_res == 1 : # 子节点有监控 父节点则为覆盖状态
return 2
if dfs(root) == 0 :
ans += 1
return ans