|
| 1 | +''' |
| 2 | +337. House Robber III |
| 3 | +The thief has found himself a new place for his thievery again. |
| 4 | +There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. |
| 5 | +After a tour, the smart thief realized that "all houses in this place forms a binary tree". |
| 6 | +It will automatically contact the police if two directly-linked houses were broken into on the same night. |
| 7 | +Determine the maximum amount of money the thief can rob tonight without alerting the police. |
| 8 | +Example 1: |
| 9 | + Input: [3,2,3,null,3,null,1] |
| 10 | + 3 |
| 11 | + / \ |
| 12 | + 2 3 |
| 13 | + \ \ |
| 14 | + 3 1 |
| 15 | +
|
| 16 | +Output: 7 |
| 17 | + Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. |
| 18 | +
|
| 19 | +Time Complexity:- O(N) |
| 20 | +Space Complexity:- O(N), as we are using dictionary to memoize the solution |
| 21 | +''' |
| 22 | + |
| 23 | +def rob(self, root: TreeNode) -> int: |
| 24 | + # this dp dictionary will help us reduce the time complexity by memoizing the solutions |
| 25 | + dp = {} |
| 26 | + |
| 27 | + # this function will return the max profit that we can get |
| 28 | + def rob_helper(root): |
| 29 | + # base cases |
| 30 | + if(root is None): |
| 31 | + return 0 |
| 32 | + # if we have the value for root in dp that we means we have calculated the value |
| 33 | + # previously so we can simply return the saved value |
| 34 | + if(root in dp.keys()): |
| 35 | + return dp[root] |
| 36 | + ''' |
| 37 | + In this problem our constraints are:- |
| 38 | + 1. If we add/rob the profit of parent then we can't add/rob profit of children |
| 39 | + as the police will be alerted |
| 40 | + 2. If we don't rob the parent then we can rob its child nodes |
| 41 | + |
| 42 | + Example:- |
| 43 | +
|
| 44 | + lvl 1 3 |
| 45 | + / \ |
| 46 | + lvl 2 2 3 |
| 47 | + \ \ |
| 48 | + lvl 3 3 1 |
| 49 | + In this if we add the profit for 3 then we can't add 2 and 3 from level 2 but add 3 and 1 from level 3 |
| 50 | + If we add 2 and 3 from level 2 then we can't add profit from level 1 and 3 |
| 51 | + Therefore, in a nutshell WE CAN'T ADD THE PROFIT OF 2 ADJACENT LEVEL/HOUSES |
| 52 | +
|
| 53 | + ''' |
| 54 | + |
| 55 | + # It is the total profit if we exclude the parent and add the left and right child |
| 56 | + profit1 = rob_helper(root.left) + rob_helper(root.right) |
| 57 | + |
| 58 | + # In this case we left child nodes and added the profit for parent node |
| 59 | + profit2 = root.val |
| 60 | + # As we robbed the parent node so we can't rob children |
| 61 | + # but we can rob children of left and right child of parent |
| 62 | + |
| 63 | + # If root.left has left and right children then add there profit |
| 64 | + if(root.left is not None): |
| 65 | + profit2 += rob_helper(root.left.left) + rob_helper(root.left.right) |
| 66 | + # If root.right has left and right children then add there profit |
| 67 | + if(root.right is not None): |
| 68 | + profit2 += rob_helper(root.right.left) + rob_helper(root.right.right) |
| 69 | + |
| 70 | + # save the max value in DP to memoize the solution |
| 71 | + dp[root] = max(profit1, profit2) |
| 72 | + |
| 73 | + return dp[root] |
| 74 | + |
| 75 | + return rob_helper(root) |
0 commit comments