968. Binary Tree Cameras

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjucor/article/details/85380470

Given a binary tree, we install cameras on the nodes of the tree. 

Each camera at a node can monitor its parent, itself, and its immediate children.

Calculate the minimum number of cameras needed to monitor all nodes of the tree.

Example 1:

Input: [0,0,null,0,0]
Output: 1
Explanation: One camera is enough to monitor all nodes if placed as shown.

Example 2:

Input: [0,0,null,0,null,0,null,null,0]
Output: 2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.


Note:

  1. The number of nodes in the given tree will be in the range [1, 1000].
  2. Every node has value 0.

思路:考虑为了计算root节点的值,需要每个子节点收集什么信息,满足什么条件,可以有哪些状态。

首先,子节点的子节点必须是合理,而子节点可以是被cover到的,也可以没有cover到(当前root节点可以cover子节点)。所以子节点有2个因素会影响父节点的计算:

1. 当前子节点有没有被cover(没有被cover的话,父节点就一定要cover当前子节点)

2. 当前子节点有没有放camera(放了的话父节点就被cover了)

所以,为了计算父节点的值,需要收集子节点3(有1种状态不可能出现)种状态的值:

1. 子节点没被cover(子节点一定没有camera)

2. 子节点被cover,而且子节点处没放camera

3. 子节点被cover,而且子节点处放了camera

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def minCameraCover(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def helper(r):
            if not r: return 0,0,float('inf')
            l0,l1,l2 = helper(r.left)
            r0,r1,r2 = helper(r.right)
            
            t0 = l1+r1
            t1 = min(l2+min(r1,r2), r2+min(l1,l2))
            t2 = 1+min(l0,l1,l2)+min(r0,r1,r2)
                        
            return t0,t1,t2
        
        _,t1,t2 = helper(root)
        return min(t1,t2)
    
        

也可以不用 “子节点没被cover” 这个状态,还是用 “有没有放camera”,这样的话就同时需要 “子节点的左子节点有没有放camera” 和 “子节点的右子节点有没有放camera”,略显麻烦。

(1)上面的思路其实是Tree之类题目的讨论,可以把类似的题目往上面的框架直接套就好了

(2)既然把计算量转移到了子节点,就不要和前面的父节点藕断丝连,比赛写的代码就是犯了这样一个错误,还把父节点的状态作为调用子节点的入参。

也可以用greedy的算法,https://leetcode.com/problems/binary-tree-cameras/discuss/211180/JavaC%2B%2BPython-Greedy-DFS

  res = 0
    def minCameraCover(self, root):
        def dfs(root):
            if not root: return 2
            if not root.left and not root.right: return 0
            l, r = dfs(root.left), dfs(root.right)
            if l == 0 or r == 0:
                self.res += 1
                return 1
            if l == 1 or r == 1:
                return 2
            return 0
        return (dfs(root) == 0) + self.res

实现起来比较tricky,还不如用前一种方法直接递归暴搜。

猜你喜欢

转载自blog.csdn.net/zjucor/article/details/85380470