Shubham Sourabhthe room · director's cutplain résumé
Room 04 · The Grind — Trees

House Robber III

MEDIUM✓ CHIP-TIMEDLC #337 — FULL STATEMENT

The briefingthe full drill, in my own words

The drill: Every house sits in a binary tree, and robbing a house auto-alerts its direct parent and children — pick the take-free subset of houses worth the most, tree-shaped instead of a line.

Houses sit as nodes in a binary tree, each holding some amount of loot, and robbing any house instantly alerts its direct parent and its direct children.

Two houses connected by a single edge can never both be robbed on the same night, but two houses two edges apart are perfectly safe together — the ban only covers immediate parent-child pairs.

The goal is picking the subset of houses that avoids every such adjacent pair while banking the largest possible total, and returning that maximum total.

  • loot values are non-negative on this course
  • tree sizes run up to tens of thousands of nodes
  • only direct parent-child pairs conflict — grandparents are safe together
  • the answer is a single maximum total, not the house list
EX 01
root = []
→ 0
empty tree
EX 02
root = [1]
→ 1
single node
EX 03
root = [5, 1, 1]
→ 5
root beats leaves

The hintstake only what you need

HINT 1 THE NUDGE

At every node you're really choosing between two totals: rob this house (its children are off-limits) or skip it (its children are fair game). Which total propagates upward depends on what the parent decides.

HINT 2 THE STRUCTURE

A node can't know whether to rob itself until it knows both outcomes for each child — robbed and not-robbed — not just one merged number.

HINT 3 ONE STEP FROM THE ANSWER

Postorder DFS returning a pair (robThis, skipThis): robThis = node.val + both children's skip values; skipThis = sum of max(rob, skip) per child. The answer is max of the pair at the root.

Coach's boardthe pattern, step by step

ROB OR SKIPPATTERN · ROB/SKIP PAIR, ONE PASSroot = [4, 1, 5, null, 2, null, 3]
STEP 1

Robbing a house bans its direct parent and children only. Postorder gives each node both outcomes before its parent needs them.

STEP 1 / 7 · ← → WORK TOO

The splitstwo paces, two languages

grind/house-robber-iii.py — RACE PACE
LANG ▸
PACE ▸
class Solution:
    def rob(self, root: Optional[TreeNode]) -> int:
        def dfs(node: Optional[TreeNode]):
            if not node:
                return (0, 0)              # (rob this, skip this)
            rob_l, skip_l = dfs(node.left)
            rob_r, skip_r = dfs(node.right)
            rob_this = node.val + skip_l + skip_r
            skip_this = max(rob_l, skip_l) + max(rob_r, skip_r)
            return (rob_this, skip_this)

        return max(dfs(root))
TIME O(N)SPACE O(H)PYTHON · RACE PACE · 12 LN

✓ CHIP-TIMEDALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED