Dynamic Programming Solutions for House Robber Problems

House Robber

class Solution:
    def rob(self, values: list[int]) -> int:
        n = len(values)
        if n == 0:
            return 0
        if n == 1:
            return values[0]
        
        prev2 = values[0]
        prev1 = max(values[0], values[1])
        
        for i in range(2, n):
            current = max(prev2 + values[i], prev1)
            prev2, prev1 = prev1, current
        
        return prev1

House Robbber II

class Solution:
    def rob(self, values: list[int]) -> int:
        n = len(values)
        if n == 0:
            return 0
        if n == 1:
            return values[0]
        
        option1 = self._rob_linear(values, 0, n - 2)
        option2 = self._rob_linear(values, 1, n - 1)
        return max(option1, option2)
    
    def _rob_linear(self, values: list[int], start: int, end: int) -> int:
        if start == end:
            return values[start]
        
        prev2 = values[start]
        prev1 = max(values[start], values[start + 1])
        
        for i in range(start + 2, end + 1):
            current = max(prev2 + values[i], prev1)
            prev2, prev1 = prev1, current
        
        return prev1

House Robbber III

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def rob(self, root: Optional[TreeNode]) -> int:
        skip, take = self._dfs(root)
        return max(skip, take)
    
    def _dfs(self, node: Optional[TreeNode]) -> tuple[int, int]:
        if not node:
            return (0, 0)
        
        left_skip, left_take = self._dfs(node.left)
        right_skip, right_take = self._dfs(node.right)
        
        # Skip current node: children can be either skipped or taken
        skip_current = max(left_skip, left_take) + max(right_skip, right_take)
        
        # Take current node: children must be skipped
        take_current = node.val + left_skip + right_skip
        
        return (skip_current, take_current)

Tags: Dynamic Programming algorithms tree traversal array Recursion

Posted on Sat, 31 Oct 2026 16:43:09 +0000 by Leonardo Dantas