Recognize the Pattern
- A parent's decision restricts which child choices are allowed.
- The best whole-tree answer differs from the value that can be extended upward.
- Child subtrees become independent once the parent decision is fixed.
Core Invariant
Each subtree returns a result for every condition its parent needs. For independent selection, those conditions are take this node and skip this node.
Important Boundary
A single subtree maximum discards the condition that made it valid. Path sums and camera coverage require different return contracts.
Write the subtree contract first
Not every bottom-up state algorithm is numeric DP. Binary Tree Cameras uses a three-state greedy rule. The shared skill is defining a state contract that retains the distinctions the parent needs.
A single best value is insufficient for house selection: the parent might forbid selecting the child. Preserve both conditional results instead of guessing which one the parent will need.
| Problem | Return to parent | Separate whole-tree decision |
|---|---|---|
| Diameter | Longest downward height | Join left and right heights. |
| Maximum path sum | Best single-branch gain | Join both branches at this node. |
| Independent house selection | [take, skip] | Choose the better root state. |
| Camera coverage | Needs, covered, or camera | Count cameras and check the root. |
Return both choices in one visit
For maximum independent weight on a tree, adjacent nodes cannot both be selected. take assumes this node is selected, forcing both children to skip. skip allows each child to choose its better state. Missing children return [0,0]. The empty selection is allowed in this general template.
Template Assumptions
- A finite binary tree with numeric val fields; adjacent parent and child cannot both be selected.
- Selecting nothing is allowed, so null returns [0, 0]. Recursion uses O(height) stack space.
JavaScript Template
- Each child subtree is visited once. There is no repeated include/exclude recursion over grandchildren.
- For the nonnegative House Robber III constraints, the same recurrence applies directly.
- The two returned numbers are conditional optima, not the two best individual houses.
Trace the example's pairs
The proof follows the contract: after fixing whether the current node is selected, there is no edge joining its two child subtrees. Optimize those subtrees independently under the chosen restriction, then combine them.
- Grandchildren 3 and 1 return [3,0] and [1,0].
- The left child 2 returns [2,3]: selecting it gives 2; skipping it permits its child worth 3.
- The right child 3 returns [3,1].
- At root 3, take = 3 + 3 + 1 = 7. skip = max(2,3) + max(3,1) = 6.
- Return max(7,6) = 7. Skipping the root does not mean taking every node on one depth level.
Step-by-Step: Child pairs combine into parent choices
- Returned pair
- Not computed
- Root [take, skip]
- Not computed
Start with unresolved subtrees
Compute children before combining their parent. A missing child returns [0,0]; the diagram shows only existing nodes.
Why path gains and coverage need different states
- For Maximum Path Sum, a completed candidate may use both children. The value returned upward may use only one, otherwise the parent creates a branching structure rather than a simple path.
- Clamp a negative child gain to zero when excluding that branch is allowed. Keep the global path answer nonempty, so an all-negative tree returns its best node, not zero.
- For cameras, a covered node without a camera cannot cover its parent. Keep COVERED distinct from CAMERA.
- A child that needs coverage takes priority over a sibling camera. The sibling's camera does not cover that child.
- A root has no parent. Resolve any final parent-dependent state explicitly.
Linear work does not guarantee stack safety
- The two-state template does constant work per node: O(N) time and O(H) recursion-stack space.
- H is O(log N) on a balanced tree but O(N) on a chain. A long valid chain can exceed JavaScript call-stack capacity.
- An explicit bottom-up order plus a Map of child states uses O(N) auxiliary space and avoids recursive calls. It is the robust variant for unbounded depth.
- Do not generalize this tree recurrence to arbitrary graphs: cycles and cross-edges break child-subtree independence.
- If the task changes to reconstructing selected nodes or handling weighted cameras, revisit the state and decision rules rather than copying this template unchanged.
Mistakes and Counterexamples
Choose either all even-depth or all odd-depth houses.
Counterexample: Root 0 has left child 10 and right child 0 with grandchild 10. A mixed-depth selection collects both 10s for 20; either whole depth parity collects only 10.
Correction: Let each child choose independently once the parent's take/skip constraint is fixed.
Return a two-branch path sum to the parent.
Counterexample: In root 10 -> child 5 with leaves 4 and 6, returning 4+5+6=15 and adding 10 reports 25. That structure branches at 5 and is not a simple path; the correct maximum is 21.
Correction: Evaluate both branches locally, but return node value plus only the better extendable child gain.
Recompute grandchildren in every take-or-skip branch.
Counterexample: On a chain, the naive recurrence repeatedly solves the same suffix: solve(i+1) and solve(i+2) call overlapping descendants again.
Correction: Return [take,skip] together in one postorder visit, or memoize equivalent subtree states. Distinct tree-state calls need not overlap when both choices are computed together.
Last-Minute Recap
- Define the parent-facing return value precisely.
- Keep mutually constrained choices separate.
- Process children once, then combine their states.
Explain It in an Interview
- Define take and skip precisely, then derive each transition.
- Why can choosing all odd or all even depths miss the optimum?
- What can be returned to a parent in maximum path sum, and what must stay a tree-wide answer?
Ready to Apply This Pattern?
Before coding, explain why this pattern fits and what must stay true at each step. Start with an easier problem, then test that reasoning on a harder variation.
Ordered from Easy to Hard. Premium access requirements still apply.
- 1.Diameter of Binary TreeReturn one downward height while evaluating a two-branch candidate locally.Easy
- 2.House Robber IIIReturn both take and skip so the parent can impose its own constraint.Medium
- 3.Binary Tree Maximum Path SumSeparate a completed path from the single branch extendable by the parent.Hard
- 4.Binary Tree CamerasKeep needs-coverage, covered, and camera states distinct; resolve the root.Hard