CMD Guide
HomeDSADynamic Programming

House thief

House Thief is a 1-D decision-DP: at each house you make a binary choice (rob it or skip it), and that choice locks out the previous house, so the optimal value at house i can only be built from the optimal values at houses i-1 and i-2 — no other history matters.

Recognize the pattern

Brute force → optimal

Brute force: recursively branch at each house into "rob" and "skip" regardless of what was chosen before, then filter to keep only the subsets that never pick two adjacent houses, and take the max valid sum. Because every house spawns two branches with no pruning, the recursion tree has exactly 2 branches per level for n levels. Cost: O(2n) time, O(n) stack space.

Optimal (DP): let dp[i] = max money stealable from the first i houses (1-indexed, value w[i]). At house i you either skip it (dp[i-1]) or rob it and add to the best achievable two houses back (dp[i-2] + w[i]), since robbing i forbids i-1.

dp[0] = 0
dp[1] = w[1]
dp[i] = max(dp[i-1], dp[i-2] + w[i])   for i >= 2
answer = dp[n]

Cost: O(n) time, O(1) space — only the last two dp values are ever read.

Complexity, derived

Time: the recurrence dp[i] = max(dp[i-1], dp[i-2]+w[i]) does exactly one comparison and one addition per index, once each, for i = 2..n → n-1 constant-work steps → O(n). Contrast the brute-force recursion described above: branching into "rob" and "skip" at every house with no pruning gives T(n) = 2·T(n-1) + O(1), which unrolls to O(2n) — the same exponential bound stated in the previous section, now derived from the recurrence rather than just the branching count. The DP is not a tighter analysis of this same recursion; it is a different formulation that recognizes only n distinct subproblems exist (one per house) instead of 2n candidate subsets, so computing each subproblem once collapses the cost to O(n).

Space: a full table costs O(n); since dp[i] only ever reads dp[i-1] and dp[i-2], two rolling variables suffice → O(1) auxiliary space.

Worked example

Input: [2, 5, 1, 3, 6, 2, 4] (indices 1..7)

iw[i]skip: dp[i-1]rob: dp[i-2]+w[i]dp[i]
122
2520+5=55
3152+1=35
4355+3=88
5685+6=1111
62118+2=1011
741111+4=1515

dp[7] = 15, matching the expected output (5 + 6 + 4). Backtracking the choices that produced each max recovers the actual houses picked.

Java (O(1) space)

class HouseThief {
    static int maxSteal(int[] w) {
        int prev2 = 0, prev1 = 0;
        for (int x : w) {
            int cur = Math.max(prev1, prev2 + x);
            prev2 = prev1;
            prev1 = cur;
        }
        return prev1;
    }
}

Pitfalls

When to use / when NOT

Use this linear DP whenever the constraint is "no two adjacent picks" over a sequence — house robbery, max sum of non-adjacent array elements, scheduling non-overlapping same-length slots on a line.

Don't use it when the exclusion is not just "adjacent" but a general interval-overlap or a weight/capacity budget — that's Weighted Interval Scheduling (sort by end time, binary-search the last compatible interval, dp[i] = max(dp[i-1], value[i] + dp[p(i)])) or 0/1 Knapsack respectively. Those handle richer constraints at the cost of O(n log n) or O(n·W) instead of O(n).

Trade-off vs brute force: DP trades the exponential 2n exploration for O(n) time by exploiting overlapping subproblems and optimal substructure; the price is that you must trust the recurrence captures every relevant case (it does here, because the only interaction between choices is immediate adjacency).

Takeaways

Recall: Why does House Thief need to look back only 2 states instead of keeping the full dp array, and under what change to the problem (e.g., can't rob 2 houses within any 3 consecutive) would that window need to grow?


Synthesized from classic "House Robber" DP formulations (e.g., LeetCode 198/213) and standard interval-scheduling/knapsack DP references for the trade-off comparison.

🤖 Don't fully get this? Learn it with Claude

Stuck on House thief? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **House thief** (DSA) and want to truly understand it. Explain House thief from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **House thief** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **House thief** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **House thief** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes