leetcode 337. 打家劫舍 III

小偷又发现一个新的可行窃的地点。 这个地区只有一个入口,称为“根”。 除了根部之外,每栋房子有且只有一个父房子。 一番侦察之后,聪明的小偷意识到“这个地方的所有房屋形成了一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

在不触动警报的情况下,计算小偷一晚能盗取的最高金额。

示例 1:


3
/ \
2 3
\ \
3 1

能盗取的最高金额 = 3 + 3 + 1 = 7.

示例 2:


3
/ \
4 5
/ \ \
1 3 1

能盗取的最高金额 = 4 + 5 = 9.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution(object):
'''
return [i, j] i is max value include root, j is max value exclude root
'''
def helper(self, root):
# corner case
if root == None:
return [0, 0]
if root.left == None and root.right == None:
return [root.val, 0]
left = self.helper(root.left)
right = self.helper(root.right)
'''
when root is included, then we only add left and right node's max value which does not include themselves
when root is not included, then we should add max of left and max of right, i.e. consider situations that either include left node or not include left node, choose the larger value
'''
return [root.val+left[1]+right[1], max(left)+max(right)]
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
return max(self.helper(root))
  • a clear solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None


'''
Let

f1(node) be the value of maximum money we can rob from the subtree with node as root ( we can rob node if necessary).

f2(node) be the value of maximum money we can rob from the subtree with node as root but without robbing node.

Then we have

f2(node) = f1(node.left) + f1(node.right) and

f1(node) = max( f2(node.left)+f2(node.right)+node.value, f2(node) ).

'''
class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
return self.robDFS(root)[1];
def robDFS(self,node):
if node is None:
return (0,0)
l = self.robDFS(node.left)
r = self.robDFS(node.right)
return (l[1] + r[1], max(l[1] + r[1], l[0] + r[0] + node.val))