这次是强盗的第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。完结,收工。