leetcode-337. 打家劫舍 III

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1. 暴力遍历所有情况 [超时]

对每一个节点都可以选择偷与不偷
对比偷与不偷的结果选择大者作为返回
注意剔除不能选择偷的情况

class Solution:
    def rob(self, root: TreeNode):
    
        reject_nodes = {}
        def deep(root):
            if root is None:
                return 0
            nonlocal reject_nodes
            if reject_nodes.get(root) is None:
                reject_nodes[root.left] = 1
                reject_nodes[root.right] = 1
                l1 = deep(root.left) + deep(root.right) + root.val
                reject_nodes[root.left] = None
                reject_nodes[root.right] = None

                l2 = deep(root.left) + deep(root.right)
                return max(l1, l2)
            else:
                return deep(root.left) + deep(root.right)
        return deep(root)

2. 优化

对于1中的逻辑 可以发现有很多重复计算 简单改造下代码缓存计算的结果

class Solution:
    def rob(self, root: TreeNode):
    
        can_rob_cache = {}
        not_rob_cache = {}
        # canRob 代表当前节点可以偷
        def deep(root, canRob):
            if root is None:
                return 0
            nonlocal can_rob_cache
            nonlocal not_rob_cache
            if canRob:
                if can_rob_cache.get(root) is not None:
                    return can_rob_cache.get(root)
                l1 = deep(root.left,  False) + deep(root.right, False) + root.val
                l2 = deep(root.left,  True) + deep(root.right, True)
                res = max(l1, l2)
                can_rob_cache[root] = res
                return res
            else:
                if not_rob_cache.get(root) is not None:
                    return not_rob_cache.get(root)
                res = deep(root.left, True) + deep(root.right, True)
                not_rob_cache[root] = res 
                return res
        return deep(root, True)

可以通过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值