LeetCode 337. House Robber III - 二叉树系列题25

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called root.

Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that all houses in this place form a binary tree. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Given the root of the binary tree, return the maximum amount of money the thief can rob without alerting the police.

Example 1:

LeetCode 337. House Robber III - 二叉树系列题25_第1张图片

Input: root = [3,2,3,null,3,null,1]
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

Example 2:

LeetCode 337. House Robber III - 二叉树系列题25_第2张图片

Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.

Constraints:

  • The number of nodes in the tree is in the range [1, 104].
  • 0 <= Node.val <= 104

题目大意是,有一个小区的房子按一定顺序连在一起,它们的连接关系使得该小区的房子形成一棵二叉树。一个小偷从根节点房子进入小区(二叉树)开始偷钱。如果树中相连的两个房子都被偷了就会触发报警器招来警察,要求算出小偷在不惊动警察的情况下最多能偷多少钱? 

问题的关键是不能连续偷两个房子,如果是从上往下偷,那么偷了当前节点就不能偷它的两个子节点;如果是从下往上偷,那么偷了当前节点就不能偷它的父节点。根据二叉树的特性,从下往上最终汇聚于根节点,最后只要判断根节点的状态,因此从下往上更方便于计算。对于一个节点有两种状态,被偷或者没被偷,它的状态取决于其左右子节点的状态:

1)当前节点被偷:它的两个子节点都没被偷

2)当前节点没被偷:不能偷如果它的两个子节点至少有一个被偷,或者小偷不想偷。

因此,从下往上传递两个值,到当前节点为止以当前节点为根节点的子树中,当前节点被偷,小偷得到的最多钱为两个子节点都没没被偷得到的最多钱加上当前节点的钱。当前节点没被偷,小偷能得到的最多钱为两个子节点所有状态中最多钱的和。

最后汇总到了根节点,根节点被偷或没被偷中的更大者就是答案。

class Solution:
    def rob(self, root: Optional[TreeNode]) -> int:
        def helper(node):
            if not node:
                return [0, 0]
            left = helper(node.left)
            right = helper(node.right)
            rob = node.val + left[1] + right[1]
            notRob = max(left) + max(right)
            return [rob, notRob]
        
        res = helper(root)
        return max(res[0], res[1])

你可能感兴趣的:(二叉树(Binary,Tree),Leetcode刷题笔记,leetcode,python,数组结构,算法,二叉树)