leetcode之 House Robber III

这次是强盗的第3篇。偷盗对象是颗二叉树,要求找到最大的利益。从给的例子来看,很容易就会看到最简单的动态规划算法。

class Solution(object):
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if root is None:
            return 0
        elif not root.left and not root.right :
            return root.val
        elif root.left and not root.right :
            return max(root.val + self.rob(root.left.left) + self.rob(root.left.right), self.rob(root.left))
        elif not root.left and root.right :
            return max(root.val + self.rob(root.right.left) + self.rob(root.right.right), self.rob(root.right))
        else :
            return max(root.val + self.rob(root.right.left) + self.rob(root.right.right) + self.rob(root.left.left) + self.rob(root.left.right), self.rob(root.left) + self.rob(root.right))

恩,所有的用例都通过了,但是。。。你懂的, TLE了。其实就跟菲波那切数列一样,算了太多重复的,那么就需要有空间存储下来。于是改进。

class Solution(object):
    def __init__(self):
        self.dict1 = {}
        self.list1 = []
    def littlerob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        value = self.dict1.get(root, -1)
        if value != -1:
            return value
        else:
            if root is None:
                return 0
            elif not root.left and not root.right :
                return root.val
            elif root.left and not root.right :
                return max(root.val + self.littlerob(root.left.left) + self.littlerob(root.left.right), self.littlerob(root.left))
            elif not root.left and root.right :
                return max(root.val + self.littlerob(root.right.left) + self.littlerob(root.right.right), self.littlerob(root.right))
            else :
                return max(root.val + self.littlerob(root.right.left) + self.littlerob(root.right.right) + self.littlerob(root.left.left) + self.littlerob(root.left.right), self.littlerob(root.left) + self.littlerob(root.right))
    def rob(self, root):
        def postorder(root):
            if root:
                if root.left:
                    postorder(root.left)
                if root.right:
                    postorder(root.right)
                self.list1.append(root)
        postorder(root)
        if self.list1 == []:
            return 0
        for i in self.list1:
            self.dict1[i] = self.littlerob(i)
        return self.dict1[root]

嗯,不错,这次的通过了。但是仔细分析可以看到多跑了一遍O(n),没办法,谁让我对后序遍历背的熟呢。。。得改进下才好。于是就有了最终版:

class Solution(object):
    def __init__(self):
        self.dict1 = {}
    def littlerob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        value = self.dict1.get(root, -1)
        if value != -1:
            return value
        else:
            if root is None:
                return 0
            elif not root.left and not root.right :
                return root.val
            elif root.left and not root.right :
                return max(root.val + self.littlerob(root.left.left) + self.littlerob(root.left.right), self.littlerob(root.left))
            elif not root.left and root.right :
                return max(root.val + self.littlerob(root.right.left) + self.littlerob(root.right.right), self.littlerob(root.right))
            else :
                return max(root.val + self.littlerob(root.right.left) + self.littlerob(root.right.right) + self.littlerob(root.left.left) + self.littlerob(root.left.right), self.littlerob(root.left) + self.littlerob(root.right))
    def rob(self, root):
        if not root:
            return 0
        if root.left:
            self.rob(root.left)
        if root.right:
            self.rob(root.right)
        self.dict1[root] = self.littlerob(root)
        return self.dict1[root]

改进了后序遍历,使其在遍历的同时进行运算,这样子还可以省掉self.list1。完结,收工。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值