2Brute2Best
🔥0
02

Path state (top-down) (Tree DFS Sub-pattern)

Carry information down a root-to-leaf path as a parameter, and check or record it when you reach a leaf.

Signals in the problem statement
  • ›

    "root-to-leaf path" with a sum, a number made of digits, or a list of paths

  • ›

    "no node on the path from the root is greater" (max so far)

  • ›

    "zigzag": the direction of the last step matters

What makes it different

Path Sum passes the remaining sum and checks only at leaves (values can be negative, so you can't stop early). Binary Tree Paths and Path Sum II keep a shared path and pop on the way back. Sum Root to Leaf Numbers carries cur * 10 + val. Count Good Nodes carries the max so far on the path, not the parent's value. Longest ZigZag carries the length for each direction you arrived from: continuing the zigzag adds 1, turning the same way twice restarts at 1.

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Path Sum
    Basic Anchor·LeetCode #112
    Easy
  2. 2
    Binary Tree Paths
    Basic Reinforcement·LeetCode #257
    Easy
  3. 3
    Sum Root to Leaf Numbers
    Slight Variation·LeetCode #129
    Medium
  4. 4
    Path Sum II
    Medium·LeetCode #113
    Medium
  5. 5
    Count Good Nodes in Binary Tree
    Pattern Transfer·LeetCode #1448
    Medium
  6. 6
    Longest ZigZag Path in a Binary Tree
    Interview-Level·LeetCode #1372
    Medium

Template

path-state-template.cpp
// Top-down: carry the path's state as a parameter; check it at the leaves.
// Here: every root-to-leaf path whose sum is target (Path Sum II).
void walk(TreeNode* node, int remaining, vector<int>& path, vector<vector<int>>& out) {
    if (!node) return;
    path.push_back(node->val);                           // enter: add this node to the path
    remaining -= node->val;
    if (!node->left && !node->right) {                   // a leaf: the path is complete
        if (remaining == 0) out.push_back(path);
    } else {
        walk(node->left, remaining, path, out);
        walk(node->right, remaining, path, out);
    }
    path.pop_back();                                     // leave: undo, so the parent's path is clean
}

vector<vector<int>> pathSum(TreeNode* root, int target) {
    vector<vector<int>> out;
    vector<int> path;
    walk(root, target, path, out);
    return out;
}
Remember this · Tree DFS
Trigger
Paths, heights, diameters, validating structure, ancestors, anything "for every subtree".
Think
If my left and right children already gave me their answers, how do I build mine?
Key question
What does my recursive function return, and what do I pass down?