House Robber medium
Problem Statement
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 a list of non-negative integers representing the amount of money of each house, determine 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.
Steps
-
Base Cases: If the input array is empty, return 0. If the array has only one house, return the amount of money in that house.
-
Dynamic Programming: We use dynamic programming to solve this problem. We create a DP array
dp
of the same size as the input arraynums
.dp[i]
represents the maximum amount of money that can be robbed up to housei
(inclusive). -
Iteration: We iterate through the
nums
array. For each housei
:- If
i
is 0,dp[i]
is simply the amount of money in house 0. - If
i
is 1,dp[i]
is the maximum of the amount of money in house 0 or house 1. - For
i
> 1,dp[i]
is the maximum of:- Robbing house
i
and adding the maximum amount robbed up to housei-2
(dp[i-2] + nums[i]
). - Not robbing house
i
and taking the maximum amount robbed up to housei-1
(dp[i-1]
).
- Robbing house
- If
-
Return Value: The maximum amount of money that can be robbed is the last element of the
dp
array,dp[nums.length - 1]
.
Explanation
The dynamic programming approach cleverly avoids adjacent house robberies. By considering the maximum robbery amount up to the previous house (dp[i-1]
) and the maximum robbery amount up to two houses before (dp[i-2] + nums[i]
), we ensure that we never rob adjacent houses. The choice between these two options at each house guarantees that we find the optimal solution.
Code
function rob(nums: number[]): number {
const n = nums.length;
if (n === 0) return 0;
if (n === 1) return nums[0];
const dp: number[] = new Array(n);
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (let i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}
Complexity
- Time Complexity: O(n), where n is the number of houses. We iterate through the
nums
array once. - Space Complexity: O(n), where n is the number of houses. We use a DP array of size n. This could be optimized to O(1) by only keeping track of the last two DP values.