Python 3.11+
The examples use the standard Python syntax and containers supported by the browser Judge; the Tree DP invariant is independent of a minor Python release.
Verify in Python docs(opens in a new tab)Aggregate dynamic-programming states from child subtrees into a result for each parent node. Learn its decision rule, maintained state, Python cost model, and transfer from a focused drill to a full Interview Problem.
Recognize it when
Consider Tree DP when the prompt's constraints and required operations match this shape: Aggregate dynamic-programming states from child subtrees into a result for each parent node.

Sign in to save your code and progress across devices. The lesson and problem statement remain public.
Tree DP defines what one node returns after solving its entire subtree. The summary may contain multiple modes because the parent needs different answers under different choices.
Solve every child before the parent, then combine independent child summaries. The recursion frame owns the parent-child relation and prevents using an unfinished subtree.
def subtree_size_trace(children,root):
trace=[]
def solve(node):
size=1+sum(solve(child) for child in children[node]);trace.append([node,size]);return size
if root!=-1:solve(root)
return traceImplement subtree_size_trace(children,root). Return [node,size] when each node completes in postorder.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
A returned path or state may need to extend through the parent, while the best answer anywhere in the subtree may combine multiple children. Track these meanings separately rather than returning an invalid shape upward.
def max_independent_sum(values,children,root):
if root==-1:return 0
def solve(node):
take=values[node];skip=0
for child in children[node]:
child_take,child_skip=solve(child);take+=child_skip;skip+=max(child_take,child_skip)
return take,skip
return max(solve(root))Implement max_independent_sum(values,children,root). Choose maximum node-value sum with no parent-child pair both chosen.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
Use ordinary tree DP when one root and child-to-parent summaries suffice. Use rerooting when the answer is required for every possible root, combining downward and parent-side contributions in two passes.
Say: “Each call returns these modes for its subtree. After all children complete, I combine their compatible states and return only information the parent can legally extend.” Count O(nodes × state combinations) time and O(height) stack.
Python 3.11+
The examples use the standard Python syntax and containers supported by the browser Judge; the Tree DP invariant is independent of a minor Python release.
Verify in Python docs(opens in a new tab)Interview bounds depend on the stated representation, input model, and real Python operations.
| Operation | Average | Worst | Interview note |
|---|---|---|---|
| Tree DP decision loop | O(n) | O(n) | Build child adjacency and return the optimal take and skip totals from each subtree. |
O(n) for the focused Choose Non-Adjacent Tree Values implementation.
These are the mistakes most likely to survive a happy-path example and fail a boundary case.
Applying the pattern without proving its ordering, monotonicity, or window invariant can silently miss valid candidates.
Prevent it: Write the decision rule beside the loop and verify it against Choose Non-Adjacent Tree Values before optimizing.
Avoid
def maximum_tree_independent_sum(parents, values):
passUse instead
def maximum_tree_independent_sum(parents, values):
if not values:
return 0
children = [[] for _ in values]
for node in range(1, len(values)):
children[parents[node]].append(node)
def solve(node):
take = values[node]
skip = 0
for child in children[node]:
child_take, child_skip = solve(child)
take += child_skip
skip += max(child_take, child_skip)
return take, skip
return max(solve(0))Where you will hit this: Choose Non-Adjacent Tree Values(opens in a new tab)
Always takes each node together with the best child state, allowing adjacent selections.
Prevent it: Use the public tests and preserve this state: A returned state summarizes the entire subtree under one explicit root condition.
Avoid
def maximum_tree_independent_sum(parents,values):
return sum(values)Use instead
def maximum_tree_independent_sum(parents, values):
if not values:
return 0
children = [[] for _ in values]
for node in range(1, len(values)):
children[parents[node]].append(node)
def solve(node):
take = values[node]
skip = 0
for child in children[node]:
child_take, child_skip = solve(child)
take += child_skip
skip += max(child_take, child_skip)
return take, skip
return max(solve(0))Where you will hit this: Choose Non-Adjacent Tree Values(opens in a new tab)
Python slicing, copying, membership in lists, or repeated sorting inside the loop can invalidate the intended complexity.
Prevent it: Count every slice, copy, sort, membership check, and container update before claiming O(n).
Avoid
def maximum_tree_independent_sum(parents,values):
return sum(values)Use instead
def maximum_tree_independent_sum(parents, values):
if not values:
return 0
children = [[] for _ in values]
for node in range(1, len(values)):
children[parents[node]].append(node)
def solve(node):
take = values[node]
skip = 0
for child in children[node]:
child_take, child_skip = solve(child)
take += child_skip
skip += max(child_take, child_skip)
return take, skip
return max(solve(0))Where you will hit this: Maximum Contiguous Subarray Sum(opens in a new tab)
Official Python documentation supports language behavior. Canonical problem pages provide additional practice context.
python-docs · checked 2026-07-27
leetcode · checked 2026-07-12