1
+ """
2
+ I learn the answer from @realisking, I couldn't come up with such elegant solution myself.
3
+
4
+ On every node we got two option, to rob or not to rob
5
+ * To rob this node, then we cannot rob our left and right child, so the max value would be the total of
6
+ * value of this node
7
+ * the max value from left child, when we not rob the left child
8
+ * the max value from right child, when we not rob the right child
9
+ * Not to rob this node, means that we can either rob or not rob our left and right child, so the max value would be the total of
10
+ * 0, because we choose not to rob this node
11
+ * the max of `rob the left child` and `not rob the left child`
12
+ * the max of `rob the right child` and `not rob the right child`
13
+
14
+ `get_max_value(node)` returns the `max value when we rob this node` and `max value when we not rob this node` on each node.
15
+ So we get the max from the two returns from `get_max_value(root)`
16
+
17
+ The time complexity is `O(LogN)`, because we keep calling `get_max_value()` until the very bottom of the tree.
18
+ The space complexity is `O(LogN)`, too. Even we only use `O(1)` of space on every `get_max_value()`
19
+ But we used `LogN` level of recursion. `N` is the number of houses.
20
+ """
1
21
class Solution (object ):
2
22
def rob (self , root ):
3
- def set_max_value (node ):
4
- if node is None : return
5
- print memo
6
- if node .left is not None :
7
- set_max_value (node .left )
8
-
9
- if node .right is not None :
10
- set_max_value (node .right )
23
+ def get_max_value (node ):
24
+ if node is None : return 0 , 0
25
+ left_rob , left_not_rob = get_max_value (node .left )
26
+ right_rob , right_not_rob = get_max_value (node .right )
11
27
12
- memo [( node , True )] = node . val + get_max_value ( node . left , False ) + get_max_value ( node .left , False )
13
- memo [( node , False )] = get_max_value ( node . left , True ) + get_max_value ( node . right , True )
28
+ rob = node .val + left_not_rob + right_not_rob
29
+ not_rob = max ( left_rob , left_not_rob ) + max ( right_rob , right_not_rob )
14
30
15
- def get_max_value (node , selected ):
16
- if node is None or (node , selected ) not in memo :
17
- print 'return 0'
18
- return 0
19
- print 'return ' , memo [(node , selected )]
20
- return memo [(node , selected )]
31
+ return rob , not_rob
21
32
22
- memo = {}
23
- set_max_value (root )
24
- return max (get_max_value (root , True ), get_max_value (root , False ))
33
+ return max (get_max_value (root ))
0 commit comments