198. House Robber

#dp

Problem

Intuition

We need to know the subsequences. As we are iterating from left to right and we need to pick non-adjacent houses.

We are generating all possible subsequences with the given constraint and maintaining max possible money we can rob. A subsequence need not be only one step away, it can be "n" steps away.

Time Complexity

Space Complexity

Solution

class Solution {
    public int rob(int[] nums) {
        // return recursiveHelper(nums.length-1, nums);
        // int[] dp = new int[nums.length];
        // Arrays.fill(dp, -1);

        // return memoizationHelper(nums.length-1, nums, dp);
        // return tabulationHelper(nums);
        return tabulationSpaceOptimizedHelper(nums);
    }

    // Dynamic Programming - Tabulation (Space-Optimized)
    private int tabulationSpaceOptimizedHelper(int[] nums) {
        // n -> Number of houses/ nums.length
        // Time Complexity: O(n)
        // Space Complexity: O(1), no extra space is used

        int n = nums.length;
        int prev2 = 0; // Max value till i-2
        int prev1 = nums[0]; // Max value till i-1

        for(int i=1; i<n; i++) {
            int f1 = nums[i] + prev2; // Max value if we rob the current house
            int f2 = prev1; // Max value if we don't rob the current house
            int current = Math.max(f1, f2); // Max value till the current house
            prev2 = prev1;
            prev1 = current;
        }

        return prev1; // Return the max value till the last house
    }

    // Dynamic Programming - Tabulation
    private int tabulationHelper(int[] nums) {
        // n -> Number of houses/ nums.length
        // Time Complexity: O(n)
        // Space Complexity: O(n), "dp" array is used

        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0]; // Base case: Max value till the first house is the value of the first house

        for(int i=1; i<n; i++) {
            int f1 = nums[i]; // Max value if we rob the current house
            if(i > 1) { // To make sure we are not stepping into negative indices
               f1 += dp[i-2]; /
            }
            int f2 = dp[i-1]; // Max value if we don't rob the current house
            dp[i] = Math.max(f1, f2); // Max value till the current house
        }

        return dp[n-1]; // Return the max value till the last house
    }

    // Dynamic Programming - Memoization
    private int memoizationHelper(int index, int[] nums, int[] dp) {
        // n -> Number of houses/ nums.length
        // Time Complexity: O(n)
        // Space Complexity: O(n), "dp" array is used

        // Base case: Max value till the first house is the value of the first house
        if(index == 0) {
            return nums[0]; 
        }

        // Base case: No more houses to rob
        if(index < 0) {
            return 0; 
        }

        if(dp[index] != -1) {
            return dp[index]; // Return the precalculated max value if already computed
        }

        // Max value if we rob the current house
        int f1 = nums[index] + memoizationHelper(index-2, nums, dp); 
        // Max value if we don't rob the current house
        int f2 = memoizationHelper(index-1, nums, dp); 
        
        // Store the computed max value in the DP table and return it
        return dp[index] = Math.max(f1, f2); 
    }

    // Recursive Approach
    private int recursiveHelper(int index, int[] nums) {
        // n -> Number of houses/ nums.length
        // Time Complexity: O(2^n), to generate all the possible subsequences
        // Space Complexity: O(n) + O(h), "dp" array is used, "h" is recursion stack

        // Base case: Max value till the first house is the value of the first house
        if(index == 0) {
            return nums[0]; 
        }

        // Base case: No more houses to rob
        if(index < 0) {
            return 0; 
        }

        // Max value if we rob the current house
        int f1 = nums[index] + recursiveHelper(index-2, nums);
        // Max value if we don't rob the current house
        int f2 = recursiveHelper(index-1, nums); 

        return Math.max(f1, f2); // Return the maximum of the two possibilities
    }
}

Last updated

Was this helpful?