|
| 1 | +from typing import List |
| 2 | + |
| 3 | + |
| 4 | +class Solution: |
| 5 | + # Dynamic Programming Take 1 |
| 6 | + # |
| 7 | + # Time: O(n) |
| 8 | + # Space: O(1) |
| 9 | + # |
| 10 | + # The sub problem at index i is: |
| 11 | + # What is the maximum amount that I can rob if we consider only the numbers from |
| 12 | + # index 0 to index i. |
| 13 | + # |
| 14 | + # It is the maximum of: |
| 15 | + # 1. maximum amount that I can rob if I consider numbers from index 0 to |
| 16 | + # index i-1. Call it prev_max. |
| 17 | + # 2. maximum amount that I can rob if I consider numbers from index 0 to |
| 18 | + # index i-2 + the number at index i. Call it curr_max. |
| 19 | + def rob(self, nums: List[int]) -> int: |
| 20 | + curr_max = prev_max = 0 |
| 21 | + for num in nums: |
| 22 | + curr_max, prev_max = max(prev_max + num, curr_max), curr_max |
| 23 | + return curr_max |
| 24 | + |
| 25 | + |
| 26 | +class SolutionTwo: |
| 27 | + # Dynamic Programming Take 2 |
| 28 | + # |
| 29 | + # Time: O(n) |
| 30 | + # Space: O(1) |
| 31 | + # |
| 32 | + # I often tend to think of DP sub problem as: What is the answer to the |
| 33 | + # optimization objective for some intermediate index i, and including the index i. |
| 34 | + # |
| 35 | + # Note that difference above is that we might not include index i. |
| 36 | + # |
| 37 | + # Then the answer to the global optimization problem is the maximum of the |
| 38 | + # optimized answers to these sub problems as we iterate over all possible index i. |
| 39 | + # |
| 40 | + # Maximum amount I can rob including house at index i is the maximum of: |
| 41 | + # 1. Maximum amount I can rob including house at index i-2 + nums[i]. |
| 42 | + # 2. Maximum amount I can rob including house at index i-3 + nums[i]. |
| 43 | + # |
| 44 | + # So, we need to keep 3 DP state variables. |
| 45 | + # Call them: |
| 46 | + # ls = last sum |
| 47 | + # lls = second last sum |
| 48 | + # llls = third last sum |
| 49 | + def rob(self, nums: List[int]) -> int: |
| 50 | + ls = lls = llls = ans = 0 |
| 51 | + for i in range(len(nums)): |
| 52 | + ls, lls, llls = max(lls + nums[i], llls + nums[i]), ls, lls |
| 53 | + ans = max(ans, ls) |
| 54 | + return ans |
0 commit comments