Skip to content

Commit 6fbaf95

Browse files
Chris WuChris Wu
authored andcommitted
house-robber-iii.py
1 parent a225d87 commit 6fbaf95

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

house-robber-iii.py

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
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+
"""
121
class Solution(object):
222
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)
1127

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)
1430

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
2132

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

Comments
 (0)