Hi👋SpeedAlgo • Deliberate Practice & Cognitive Ergonomics for Software Engineers

An interactive algorithm mastery and technical interview preparation platform published by Hi👋WebEnterprise. Built for senior and staff software engineers preparing for rigorous coding screens at top tech companies (FAANG/MAMAA).

13 Core Algorithmic Patterns & 225 Practice Problems

  • 1. Two Pointers (16 Paradigms, 43 Problems): Opposite ends, sorted pair sums, palindrome verification, trapping rain water, 3Sum, container with most water — includes the Sliding Window and Fast & Slow Pointers paradigms (contiguous subarray invariants, longest substrings, Floyd's cycle detection, linked list middle).
  • 2. Binary Search (9 Paradigms, 14 Problems): Monotonic predicate partitioning (feasible(x)), boundary search, rotated sorted arrays, square roots, minimum ship capacity, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (5 Paradigms, 11 Problems): Counting set bits, XOR cancellation, bit reversal, bitmask pairing, maximum XOR with a bitwise trie.
  • 4. Math & Geometry (8 Paradigms, 14 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (15 Paradigms, 24 Problems): Path sums, lowest common ancestor, tree diameter, validating BSTs, tree DP (House Robber III, Binary Tree Cameras).
  • 6. Tree/Graph Breadth-First Search (5 Paradigms, 12 Problems): Level-order traversals, shortest path in unweighted graphs, zig-zag traversals, rotting oranges, word ladders.
  • 7. Graphs (12 Paradigms, 22 Problems): Topological sort, cycle detection, Dijkstra's algorithm, bipartite graph validation, network delay.
  • 8. Backtracking (6 Paradigms, 14 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens, Sudoku solver.
  • 9. Dynamic Programming (13 Paradigms, 28 Problems): Memoization vs tabulation, 0/1 knapsack, unbounded knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (9 Paradigms, 11 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (7 Paradigms, 17 Problems): Trie (prefix tree), Union-Find (Disjoint Set Union), LRU Cache, LFU Cache, range-sum queries with updates.
  • 12. Stack (5 Paradigms, 9 Problems): Next greater element, largest rectangle in histogram, remove k digits, decode string, min stack.
  • 13. Intervals & Greedy (2 Paradigms, 6 Problems): Merge intervals, interval scheduling, meeting rooms by sweep line, jump game.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Read the pattern's mental model, loop invariant and Big-O proof, compare the pattern's template with the problem's solution side by side, and use the step-by-step debugger. The solution can also be shown in C#, Java, TypeScript, C++, Go or Rust for almost every problem.
  2. Stage 2 (Active Recall): Rebuild the solution from memory in a code editor, with an invariant checklist and optional progressive hints, and check it against a judged test suite.
  3. Stage 3 (AI Interview Coach, coming soon): A mock-interview stage still in development; for now, students go straight from Stage 2 to Stage 4.
  4. Stage 4 (Solve on Your Own): Solve a new problem on your own against a 15-minute timer; your code is graded against a test suite. Python and TypeScript run in your browser and C# runs on our server (design problems grade in Python and TypeScript).

Equipped with a spaced-repetition review hub on a fixed 7-step schedule (1 day up to 90 days), a two-pane Studio workspace, and study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Coins: New accounts get 40 free coins once, the daily claim adds +20 coins once a day, and inviting a friend earns you +25 coins when they complete their first practice step. These are the only ways to earn coins.
  • AI Coach: Each AI coach question costs 1-5 coins, priced by the server according to its size.
  • BYOK (Bring Your Own Key): AI coaching is free with your own Google Gemini, OpenAI or OpenRouter API key (BYOK).
  • Extras: Coins also unlock extras for 24 hours: a Recall hint level (1 coin), a Solve solution reveal (2), a LeetCode problem card's solutions (1) and a pattern's extra canonical problems (1).
  • Payments & Refunds: Nothing on the site is sold for money: coins can only be earned, never bought. There are no subscriptions or charges, so there is nothing to refund.
  • Platform Operator: Hi👋WebEnterprise. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

Arena
238Items
Theory Context•Depth-First Search (DFS)
EasyLC 94

Binary Tree Inorder Traversal (LeetCode 94)

A binary tree is given by its root. Return the values of its nodes in inorder. Inorder lists, for every node, the values of its left subtree first, then the value of the node itself, then the values of its right subtree.

The tree is not necessarily a search tree: values can repeat and can come in any order.

Follow-up: the recursive walk is short. Can you write the walk with a stack of your own instead?

Worked Examples

Example 1
Input:root = [1,null,2,3]
Output:[1,3,2]
132
Explanation: Node 1 has no left subtree, so 1 comes first. Its right subtree is node 2 with the left child 3. Inside that subtree, 3 comes before 2.
Example 2
Input:root = [1,2,3,4,5,null,8,null,null,6,7,9]
Output:[4,2,6,5,7,1,3,9,8]
426571398
Explanation: The left subtree of node 1 gives 4, 2, 6, 5, 7. Then comes 1. The right subtree gives 3, 9, 8, because node 3 has no left child and node 8 has the left child 9.
Example 3
Input:root = []
Output:[]
Empty tree (root = null)
Explanation: An empty tree has no values to list.
Example 4
Input:root = [1]
Output:[1]
1
Explanation: A tree with one node lists that node.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [0, 100].

  • -100 <= Node.val <= 100

Deep-Dive & Conceptual Insights

Core Insight

A depth-first walk reaches every node three times: on the way down, after its left subtree and after its right subtree. Inorder lists the node at the second time, which is when stack.pop() hands the node back, so result.append(node.val) goes right after the pop.

Real-World Scenario & Production Applications

Programs that print or export a tree must choose an order. A file manager lists a folder before the files inside it, which is preorder. A search tree that a database keeps for an index is read in sorted order, which is inorder. A program that deletes a folder must remove the files inside it first, which is postorder. All three orders are the same walk, with the visit placed at a different moment.

Step-by-Step Execution Trace Table

Example 1, root = [1,null,2,3]. The columns show the state after each row:

StepWhat runsstack (bottom to top)noderesultWhat it means
1Dive: stack.append(node), node = node.left[1]None[]1 is pushed, not visited: its left subtree comes first
2node = stack.pop(), result.append(node.val), node = node.right[]2[1]1 has no left subtree, so it is visited now; the walk goes right
3Dive: push 2, then push 3[2, 3]None[1]3 is the left child of 2, so 2 must wait
4Pop 3, append, node = node.right[2]None[1, 3]3 is visited before 2
5Pop 2, append, node = node.right[]None[1, 3, 2]node is None and stack is empty, so the loop ends

Appending when a node is pushed would add 1, then 2, then 3, and return the preorder [1, 2, 3].

Trace Inputroot = [1,null,2,3]
Expected[1,3,2]

Example 1, root = [1,null,2,3]. The columns show the state after each row:

StepWhat runsstack (bottom to top)noderesultWhat it means
1Dive: stack.append(node), node = node.left[1]None[]1 is pushed, not visited: its left subtree comes first
2node = stack.pop(), result.append(node.val), node = node.right[]2[1]1 has no left subtree, so it is visited now; the walk goes right
3Dive: push 2, then push 3[2, 3]None[1]3 is the left child of 2, so 2 must wait
4Pop 3, append, node = node.right[2]None[1, 3]3 is visited before 2
5Pop 2, append, node = node.right[]None[1, 3, 2]node is None and stack is empty, so the loop ends

Appending when a node is pushed would add 1, then 2, then 3, and return the preorder [1, 2, 3].

Code Shape
Archetype Code Shape
Python
1A depth-first walk reaches each node three times: on the way down, after its left subtree, and after its right subtree. The order name says which time lists the node.
2Keep `stack` and `node = root`, and loop `while node or stack`: an inner `while node` pushes and moves to `node.left`, then pop, append `node.val` and move to `node.right`.
3Preorder appends at the push, inorder at the pop, and postorder only when `top.right` is empty or `top.right is last`.
4The trap: append after the pop in inorder. Appending at the push returns the preorder, `[1, 2, 3]` instead of `[1, 3, 2]` on `[1,null,2,3]`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

A tree has no first, second and third element, so a list of its nodes needs a rule for the order. A depth-first walk reaches every node three times: on the way down, when it comes back from the left subtree, and when it comes back from the right subtree. The three visit orders differ only in which of those times adds the node to the list. Preorder lists the node on the way down, inorder after its left subtree, and postorder after its right subtree.

📚 The Analogy: A Folder Tree

A folder holds files and other folders. To copy the tree you create each folder before the things inside it: that is preorder. To delete the tree you remove the things inside a folder before the folder itself, because a folder with contents cannot be removed: that is postorder. Inorder needs two children, so it fits a binary tree: the node comes between its left and right subtrees. In a binary search tree that is exactly sorted order.

🔑 Why It Works

Recursion keeps the nodes that are waiting for the walk to come back in the call stack. An explicit stack keeps the same nodes in a list that you control. The inner loop pushes every node on the way down the left edge, so the node that stack.pop() returns has a finished left subtree. Appending its value right after the pop lists it between its two subtrees, and node = node.right starts the right subtree. Each node is pushed once and popped once.

  • Appending node.val when node is pushed

  • Looping while stack instead of while node or stack

  • Popping a node in postorder without checking top.right is not last

  • Comparing top.right.val with last.val instead of the nodes

  • Walking a deep tree with recursion

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Return the inorder traversal of its nodes' values" names an order, and the follow-up asks for the walk without recursion. A list of the nodes in a named visit order is Tree Traversals: one walk, with the visit placed at the moment the order name says.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Before each stack.pop(), every value in result comes before every node still on stack, in inorder. The popped node has a finished left subtree, so result.append(node.val) adds the next value, and node = node.right starts the right subtree.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: result.append(node.val) goes after stack.pop(), never next to stack.append(node). At the push, the list is the preorder, [1, 2, 3] instead of [1, 3, 2] on [1,null,2,3].

  • while node or stack, never while stack: stack is empty at the start, so while stack returns [].

  • root = [] gives node = None and an empty stack, so the loop never runs and result is []. Code that reads root.val first fails on this input.

  • The recursion is safe here, because the tree has at most 100 nodes. A chain of 3000 nodes raises RecursionError, which is why the explicit stack is the form to know.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd solve this with Tree Traversals on an explicit stack. Inorder means left subtree, then the node, then the right subtree. I keep a stack of the nodes whose left subtree is still being walked. From a node, I push it and move to its left child, again and again, until there is no left child. Then I pop one node. Its left subtree is finished, so I append its value to the result. Then I move to its right child, and the same dive starts again. The loop runs while there is a current node or the stack is not empty, because the stack can be empty while a right subtree is still waiting. The trap is where I append: after the pop, never at the push, or I would return the preorder. Each node is pushed once and popped once, so the time is order N, and the stack holds at most the height of the tree, so the space is order H.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the code: the inner while node: loop pushes one node per pass, and the outer loop pops one node per pass. A node is pushed when the walk first reaches it, and it is popped once, after its left subtree. Nothing pushes a node a second time, because node = node.right moves to a node that has never been pushed. So the walk makes N pushes and N pops, and each push, pop and append is O(1). Total: O(N).

SPACE COMPLEXITY

O(H) stack

Every node on stack is an ancestor of node whose left subtree is still being walked, so stack holds at most one root-to-leaf path: O(H) nodes, where H is the height of the tree. The returned list holds N values; it is the output and is not counted.

Formal Recurrence Relation

T(N)=N⋅(push+pop+append)=O(N)T(N) = N \cdot (\text{push} + \text{pop} + \text{append}) = O(N)T(N)=N⋅(push+pop+append)=O(N)

Derivation Progression

Pushes

N pushes

stack.append(node) runs once for each node, when the dive reaches it.

Pops and appends

N pops and N appends

Each pass of while node or stack: pops one node and appends its value; the loop ends when every node has been popped.

Moves to the right

N assignments

node = node.right runs once per pop and moves to a subtree that has not been pushed yet.

Total

O(N)

Each push, pop, append and assignment is O(1).

Variable Definitions

NNN

Number of nodes in the tree (0 to 100 here)

HHH

Height of the tree: about log N when balanced, up to N on a chain

Memory Architecture & Bounds

🟣 Call Stack

O(1): iterative, no recursion

🔵 Auxiliary Heap

O(H): stack holds one root-to-leaf path at most

🟢 Output Space

O(N): the returned list (not counted)

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): every node is visited, whatever the shape

Average Case

O(N)O(N)O(N) time and O(log⁡N)O(\log N)O(logN) stack on a balanced tree

Worst Case

O(N)O(N)O(N) time; the stack grows to O(N)O(N)O(N) on a chain that leans left

Graph & Tree Traversal Frontier

Graph & Tree Traversal Frontier
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "inorder traversal", "could you do it iteratively?". A named visit order plus a request to avoid recursion: Tree Traversals with an explicit stack.

CONSTRAINTS & BOUNDS

0≤N≤1000 \le N \le 1000≤N≤100 nodes and values in [−100,100][-100, 100][−100,100]. One walk is O(N)O(N)O(N) time, and stack holds one root-to-node path, O(H)O(H)O(H), which is at most 100 here, so recursion would also work. Binary Search Tree Iterator (LC 173) allows 10510^5105 nodes in one chain, which passes Python's default recursion limit of 1000.

FAANG PRODUCTION TRAPS & EDGE CASES

Appending node.val at the push returns the preorder, and while stack never starts. A walk that is paused between calls, such as an iterator, must keep stack and node as fields of an object, because local variables are lost when the function returns.

Theory Context•Depth-First Search (DFS)
EasyLC 94

Binary Tree Inorder Traversal (LeetCode 94)

A binary tree is given by its root. Return the values of its nodes in inorder. Inorder lists, for every node, the values of its left subtree first, then the value of the node itself, then the values of its right subtree.

The tree is not necessarily a search tree: values can repeat and can come in any order.

Follow-up: the recursive walk is short. Can you write the walk with a stack of your own instead?

Worked Examples

Example 1
Input:root = [1,null,2,3]
Output:[1,3,2]
132
Explanation: Node 1 has no left subtree, so 1 comes first. Its right subtree is node 2 with the left child 3. Inside that subtree, 3 comes before 2.
Example 2
Input:root = [1,2,3,4,5,null,8,null,null,6,7,9]
Output:[4,2,6,5,7,1,3,9,8]
426571398
Explanation: The left subtree of node 1 gives 4, 2, 6, 5, 7. Then comes 1. The right subtree gives 3, 9, 8, because node 3 has no left child and node 8 has the left child 9.
Example 3
Input:root = []
Output:[]
Empty tree (root = null)
Explanation: An empty tree has no values to list.
Example 4
Input:root = [1]
Output:[1]
1
Explanation: A tree with one node lists that node.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [0, 100].

  • -100 <= Node.val <= 100

Deep-Dive & Conceptual Insights

Core Insight

A depth-first walk reaches every node three times: on the way down, after its left subtree and after its right subtree. Inorder lists the node at the second time, which is when stack.pop() hands the node back, so result.append(node.val) goes right after the pop.

Real-World Scenario & Production Applications

Programs that print or export a tree must choose an order. A file manager lists a folder before the files inside it, which is preorder. A search tree that a database keeps for an index is read in sorted order, which is inorder. A program that deletes a folder must remove the files inside it first, which is postorder. All three orders are the same walk, with the visit placed at a different moment.

Step-by-Step Execution Trace Table

Example 1, root = [1,null,2,3]. The columns show the state after each row:

StepWhat runsstack (bottom to top)noderesultWhat it means
1Dive: stack.append(node), node = node.left[1]None[]1 is pushed, not visited: its left subtree comes first
2node = stack.pop(), result.append(node.val), node = node.right[]2[1]1 has no left subtree, so it is visited now; the walk goes right
3Dive: push 2, then push 3[2, 3]None[1]3 is the left child of 2, so 2 must wait
4Pop 3, append, node = node.right[2]None[1, 3]3 is visited before 2
5Pop 2, append, node = node.right[]None[1, 3, 2]node is None and stack is empty, so the loop ends

Appending when a node is pushed would add 1, then 2, then 3, and return the preorder [1, 2, 3].

Trace Inputroot = [1,null,2,3]
Expected[1,3,2]

Example 1, root = [1,null,2,3]. The columns show the state after each row:

StepWhat runsstack (bottom to top)noderesultWhat it means
1Dive: stack.append(node), node = node.left[1]None[]1 is pushed, not visited: its left subtree comes first
2node = stack.pop(), result.append(node.val), node = node.right[]2[1]1 has no left subtree, so it is visited now; the walk goes right
3Dive: push 2, then push 3[2, 3]None[1]3 is the left child of 2, so 2 must wait
4Pop 3, append, node = node.right[2]None[1, 3]3 is visited before 2
5Pop 2, append, node = node.right[]None[1, 3, 2]node is None and stack is empty, so the loop ends

Appending when a node is pushed would add 1, then 2, then 3, and return the preorder [1, 2, 3].

Code Shape
Archetype Code Shape
Python
1A depth-first walk reaches each node three times: on the way down, after its left subtree, and after its right subtree. The order name says which time lists the node.
2Keep `stack` and `node = root`, and loop `while node or stack`: an inner `while node` pushes and moves to `node.left`, then pop, append `node.val` and move to `node.right`.
3Preorder appends at the push, inorder at the pop, and postorder only when `top.right` is empty or `top.right is last`.
4The trap: append after the pop in inorder. Appending at the push returns the preorder, `[1, 2, 3]` instead of `[1, 3, 2]` on `[1,null,2,3]`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

A tree has no first, second and third element, so a list of its nodes needs a rule for the order. A depth-first walk reaches every node three times: on the way down, when it comes back from the left subtree, and when it comes back from the right subtree. The three visit orders differ only in which of those times adds the node to the list. Preorder lists the node on the way down, inorder after its left subtree, and postorder after its right subtree.

📚 The Analogy: A Folder Tree

A folder holds files and other folders. To copy the tree you create each folder before the things inside it: that is preorder. To delete the tree you remove the things inside a folder before the folder itself, because a folder with contents cannot be removed: that is postorder. Inorder needs two children, so it fits a binary tree: the node comes between its left and right subtrees. In a binary search tree that is exactly sorted order.

🔑 Why It Works

Recursion keeps the nodes that are waiting for the walk to come back in the call stack. An explicit stack keeps the same nodes in a list that you control. The inner loop pushes every node on the way down the left edge, so the node that stack.pop() returns has a finished left subtree. Appending its value right after the pop lists it between its two subtrees, and node = node.right starts the right subtree. Each node is pushed once and popped once.

  • Appending node.val when node is pushed

  • Looping while stack instead of while node or stack

  • Popping a node in postorder without checking top.right is not last

  • Comparing top.right.val with last.val instead of the nodes

  • Walking a deep tree with recursion

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Return the inorder traversal of its nodes' values" names an order, and the follow-up asks for the walk without recursion. A list of the nodes in a named visit order is Tree Traversals: one walk, with the visit placed at the moment the order name says.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Before each stack.pop(), every value in result comes before every node still on stack, in inorder. The popped node has a finished left subtree, so result.append(node.val) adds the next value, and node = node.right starts the right subtree.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: result.append(node.val) goes after stack.pop(), never next to stack.append(node). At the push, the list is the preorder, [1, 2, 3] instead of [1, 3, 2] on [1,null,2,3].

  • while node or stack, never while stack: stack is empty at the start, so while stack returns [].

  • root = [] gives node = None and an empty stack, so the loop never runs and result is []. Code that reads root.val first fails on this input.

  • The recursion is safe here, because the tree has at most 100 nodes. A chain of 3000 nodes raises RecursionError, which is why the explicit stack is the form to know.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd solve this with Tree Traversals on an explicit stack. Inorder means left subtree, then the node, then the right subtree. I keep a stack of the nodes whose left subtree is still being walked. From a node, I push it and move to its left child, again and again, until there is no left child. Then I pop one node. Its left subtree is finished, so I append its value to the result. Then I move to its right child, and the same dive starts again. The loop runs while there is a current node or the stack is not empty, because the stack can be empty while a right subtree is still waiting. The trap is where I append: after the pop, never at the push, or I would return the preorder. Each node is pushed once and popped once, so the time is order N, and the stack holds at most the height of the tree, so the space is order H.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the code: the inner while node: loop pushes one node per pass, and the outer loop pops one node per pass. A node is pushed when the walk first reaches it, and it is popped once, after its left subtree. Nothing pushes a node a second time, because node = node.right moves to a node that has never been pushed. So the walk makes N pushes and N pops, and each push, pop and append is O(1). Total: O(N).

SPACE COMPLEXITY

O(H) stack

Every node on stack is an ancestor of node whose left subtree is still being walked, so stack holds at most one root-to-leaf path: O(H) nodes, where H is the height of the tree. The returned list holds N values; it is the output and is not counted.

Formal Recurrence Relation

T(N)=N⋅(push+pop+append)=O(N)T(N) = N \cdot (\text{push} + \text{pop} + \text{append}) = O(N)T(N)=N⋅(push+pop+append)=O(N)

Derivation Progression

Pushes

N pushes

stack.append(node) runs once for each node, when the dive reaches it.

Pops and appends

N pops and N appends

Each pass of while node or stack: pops one node and appends its value; the loop ends when every node has been popped.

Moves to the right

N assignments

node = node.right runs once per pop and moves to a subtree that has not been pushed yet.

Total

O(N)

Each push, pop, append and assignment is O(1).

Variable Definitions

NNN

Number of nodes in the tree (0 to 100 here)

HHH

Height of the tree: about log N when balanced, up to N on a chain

Memory Architecture & Bounds

🟣 Call Stack

O(1): iterative, no recursion

🔵 Auxiliary Heap

O(H): stack holds one root-to-leaf path at most

🟢 Output Space

O(N): the returned list (not counted)

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): every node is visited, whatever the shape

Average Case

O(N)O(N)O(N) time and O(log⁡N)O(\log N)O(logN) stack on a balanced tree

Worst Case

O(N)O(N)O(N) time; the stack grows to O(N)O(N)O(N) on a chain that leans left

Graph & Tree Traversal Frontier

Graph & Tree Traversal Frontier
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "inorder traversal", "could you do it iteratively?". A named visit order plus a request to avoid recursion: Tree Traversals with an explicit stack.

CONSTRAINTS & BOUNDS

0≤N≤1000 \le N \le 1000≤N≤100 nodes and values in [−100,100][-100, 100][−100,100]. One walk is O(N)O(N)O(N) time, and stack holds one root-to-node path, O(H)O(H)O(H), which is at most 100 here, so recursion would also work. Binary Search Tree Iterator (LC 173) allows 10510^5105 nodes in one chain, which passes Python's default recursion limit of 1000.

FAANG PRODUCTION TRAPS & EDGE CASES

Appending node.val at the push returns the preorder, and while stack never starts. A walk that is paused between calls, such as an iterator, must keep stack and node as fields of an object, because local variables are lost when the function returns.

© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•