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 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.
Examples
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.
Constraints
1 <= nums.length <= 100
0 <= nums[i] <= 400
Intuition
This problem is a great fit for solving with recursion. Let's try to tackle it using the recursive framework we explored in The Recursive Journey blog:
- Identify actual problem: The actual problem here is to find the maximum loot that we can acquire by robbing houses.
$$max(rob(nums))$$
Identify sub-problem: If we can rob
nth
house then we can rob(n-2)th
house similarly(i-2th)
house.Trust that the base function works: We have confidence in the function that computes the loot. It is designed to work effectively for all sub-problems and deliver the accurate solution.
Link actual and sub-problem: Since we have found
robHouse(n-2)
androbHouse(n-1)
we can just do:
robHouse(n) = max(robHouse(n-2),robHouse(n-1))
Identify base case: Since we're moving from the
nth index
of thenums
array to the0th index
, we cannot exceed the 0th index. Therefore:if house<0: return 0
This will make sure recursive function does not go beyond the bounds of nums array.
If you observe, we can solve this issue by moving through the cost array in two directions:
from the
0th to the nth
indexfrom the
nth to the 0th
index.The explanation above covers moving through the cost array from the nth index to the 0th index.
The concept for moving through the cost array from the
0th index to the nth
index remains the same. Only the code we write and the base condition change slightly. Below, we will see code solutions for both approaches.
Code Solution
Going from 0 to n
Python Code:
# TC: O(2^n)
# SC: O(n)
class Solution:
def rob(self, nums: List[int]) -> int:
# call recursive function to calculate maximum loot
# return the maximum loot
return self.robHouse(0,len(nums),nums)
def robHouse(self,house,n:int,nums:List[int]):
# base case
# since can't rob a house that's not there in the array
# we return 0
if house>=n:
return 0
# recursive case of robbing the current house
rob= nums[house]+self.robHouse(house+2,n,nums)
# recursive ase of not robbing the current house
dont_rob=self.robHouse(house+1,n,nums)
# return maximum of rob and dont_rob
return max(rob,dont_rob)
Going from n to 0
Go Code:
// TC: O(2^n)
// SC: O(n)
func rob(nums []int) int {
// call the recursive function to calculate loot
// and return maximum loot
return robHouse(len(nums)-1,nums)
}
func robHouse(house int, nums []int) int{
// base case
// we return 0 if house is less than 0
// as array can't have -ve size
if house<0{
return 0
}
// recursive of ronning the current house
rob:=nums[house]+robHouse(house-2,nums)
// recursive case of not robbing the current house
dontRob:=robHouse(house-1,nums)
// return the maximum of rob and dontRob
return max(rob,dontRob)
}
func max(a,b int) int{
if a>b{
return a
}
return b
}
Time and Space complexity
Time Complexity:
$$O(2^n)$$
As for each recursive call we will make two more recursive calls.
Space Complexity:
$$O(n)$$
This is the space allocated for recursive call stack.
Conclusion
As you can see 198. House Robber can be solved using recursion. There are two ways to solve this problem using recursion:
from the
0th to the nth
indexfrom the
nth to the 0th
index
Although these are decent solutions, they're just basic recursion without any fancy optimizations. But hey, no worries, we'll dive into those optimizations in the Dynamic Programming series.
I hope you got something useful from this blog post. If you've made it this far, please give it a like and drop your thoughts in the comments. Feel free to share any ideas for making future blog posts better.