2021-09-05 19:46:10 +02:00
|
|
|
|
# You are a professional robber planning to rob houses along a street.
|
|
|
|
|
# Each house has a certain amount of money stashed, the only constraint stopping you
|
|
|
|
|
# from robbing each of them is that adjacent houses have security systems connected
|
|
|
|
|
# and it will automatically contact the police if two adjacent houses
|
|
|
|
|
# were broken into on the same night.
|
|
|
|
|
#
|
|
|
|
|
# Given an integer array nums representing the amount of money of each house,
|
|
|
|
|
# return the maximum amount of money you can rob tonight without alerting the police.
|
|
|
|
|
#
|
|
|
|
|
# Example 1:
|
|
|
|
|
#
|
|
|
|
|
# Input: nums = [1,2,3,1]
|
|
|
|
|
# Output: 4
|
|
|
|
|
# Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
|
|
|
|
|
# Total amount you can rob = 1 + 3 = 4.
|
|
|
|
|
#
|
|
|
|
|
# Example 2:
|
|
|
|
|
#
|
|
|
|
|
# Input: nums = [2,7,9,3,1]
|
|
|
|
|
# Output: 12
|
|
|
|
|
# Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
|
|
|
|
|
# Total amount you can rob = 2 + 9 + 1 = 12.
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Approach 1: Dynamic Programming
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# Complexity Analysis
|
|
|
|
|
#
|
|
|
|
|
# Time Complexity: O(N) since we process at most N recursive calls, thanks to
|
|
|
|
|
# caching, and during each of these calls, we make an O(1) computation which is
|
|
|
|
|
# simply making two other recursive calls, finding their maximum, and populating
|
|
|
|
|
# the cache based on that.
|
|
|
|
|
#
|
|
|
|
|
# Space Complexity: O(N) which is occupied by the cache and also by the recursion stack
|
|
|
|
|
|
|
|
|
|
def rob(nums, i = nums.length - 1)
|
|
|
|
|
return 0 if i < 0
|
|
|
|
|
|
|
|
|
|
[rob(nums, i - 2) + nums[i], rob(nums, i - 1)].max
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nums = [1, 2, 3, 1]
|
|
|
|
|
puts rob(nums)
|
|
|
|
|
# Output: 4
|
|
|
|
|
|
|
|
|
|
nums = [2, 7, 9, 3, 1]
|
|
|
|
|
puts rob(nums)
|
|
|
|
|
# Output: 12
|
2021-09-05 19:46:24 +02:00
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Approach 2: Optimized Dynamic Programming
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# Time Complexity
|
|
|
|
|
#
|
|
|
|
|
# Time Complexity: O(N) since we have a loop from N−2 and we use the precalculated
|
|
|
|
|
# values of our dynamic programming table to calculate the current value in the table
|
|
|
|
|
# which is a constant time operation.
|
|
|
|
|
#
|
|
|
|
|
# Space Complexity: O(1) since we are not using a table to store our values.
|
|
|
|
|
# Simply using two variables will suffice for our calculations.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
def rob(nums)
|
|
|
|
|
dp = Array.new(nums.size + 1)
|
|
|
|
|
|
|
|
|
|
(nums.size + 1).times do |i|
|
|
|
|
|
dp[i] = if i == 0
|
|
|
|
|
0
|
|
|
|
|
elsif i == 1
|
|
|
|
|
nums[0]
|
|
|
|
|
else
|
|
|
|
|
[dp[i - 2] + nums[i - 1], dp[i - 1]].max
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
dp[-1]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nums = [1, 2, 3, 1]
|
|
|
|
|
puts rob(nums)
|
|
|
|
|
# Output: 4
|
|
|
|
|
|
|
|
|
|
nums = [2, 7, 9, 3, 1]
|
|
|
|
|
puts rob(nums)
|
|
|
|
|
# Output: 12
|