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).

12 Core Algorithmic Patterns & 142 Practice Problems

  • 1. Two Pointers (5 Paradigms, 25 Problems): Converging pointers, sorted pair sums, container with most water, trapping rain water, 3Sum, plus the Sliding Window and Fast & Slow Pointers paradigms (Floyd cycle detection, monotonic window invariants, longest substrings, minimum window).
  • 2. Binary Search (7 Paradigms, 10 Problems): Monotonic predicate partitioning, boundary searching, rotated arrays, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (4 Paradigms, 7 Problems): Bitmasking, XOR tricks, counting set bits, subset enumeration via bitmasks.
  • 4. Math & Geometry (4 Paradigms, 9 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (6 Paradigms, 15 Problems): Path sums, lowest common ancestor, tree diameter, subtree serialization, validating BSTs.
  • 6. Tree/Graph Breadth-First Search (4 Paradigms, 11 Problems): Level-order traversals, shortest path, rotting oranges, word ladders.
  • 7. Graphs (5 Paradigms, 13 Problems): Topological sort, cycle detection, Dijkstra, bipartite validation, network delay.
  • 8. Backtracking (8 Paradigms, 12 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens.
  • 9. Dynamic Programming (6 Paradigms, 13 Problems): Memoization vs tabulation, knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (6 Paradigms, 8 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (3 Paradigms, 10 Problems): Trie, Union-Find, LRU Cache, LFU Cache, Monotonic Stacks.
  • 12. Intervals & Stack / Miscellaneous (2 Paradigms, 9 Problems): Merge intervals, daily temperatures, largest rectangle in histogram, trapping rain water via stack.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Multi-language Rosetta Stone contrasting abstract invariants with concrete solutions across Python, C#, Java, TypeScript, C++, Go, and Rust.
  2. Stage 2 (Active Recall): Reconstruct algorithmic template invariants from memory with real-time feedback before looking at solutions.
  3. Stage 3 (Senior SWE AI Mock Coach): Simulated senior mock interview evaluating Big-O space/time tradeoffs, edge cases, and code reviews in Monaco Editor.
  4. Stage 4 (Solve on Your Own): Timed sandbox challenges verified against automated test suites in Python, C#, Java, and TypeScript.

Equipped with SM-2 Spaced Repetition Review Hub, Studio Cockpit workspace layout, and interactive study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Compute Coins: 40 free coins upon signup, +20 daily login bonus, +25 referral bonus.
  • 24-Hour AI Coaching Pass: 5 compute coins unlocks unlimited senior SWE AI coaching for a full 24 hours.
  • BYOK (Bring Your Own Key): Completely free unlimited AI coaching if using your own Gemini/OpenAI API key.
  • Refund & Subscription Policy: No recurring charges, no subscription traps, and no paid paywalls. Free tier provides full learning path.
  • Platform Operator: Hi👋WebEnterprise Inc. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

148Items
Theory Context•Depth-First Search (DFS)
EasyLC 543

Diameter of Binary Tree (LeetCode 543)

Height Return + Global Extremum: The Longest Path May Bend at Any Node

Target Frequency:MetaAmazonGoogleMicrosoft

You are given the root of a binary tree. The diameter is the length of the longest path between any two nodes, measured as the number of edges on that path. The path does not have to pass through the root. Return the diameter.

Worked Examples

Example 1
Input:root = [1,2,3,4,5]
Output:3
Explanation: The path 4 -> 2 -> 1 -> 3 (or 5 -> 2 -> 1 -> 3) has 3 edges, and no path is longer.
Example 2
Input:root = [1,2]
Output:1
Explanation: The only path joins the two nodes with a single edge.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [1, 104].

  • -100 <= Node.val <= 100

Deep-Dive & Conceptual Insights

Why It Works & Core Invariant

Every path has one highest node where it bends. At each node, the longest path bending there has height(left) + height(right) edges. Record that in a global, but return only 1 + max(left, right), because a parent can extend just one straight branch.

Real-World Scenario & Production Applications

Worst-case hop count between two devices in a tree-shaped network, the longest chain between any two people in an org chart, the widest span of a river delta.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Boundary & State Setup

Establish initial problem boundaries and state invariants such that the valid search space is fully bounded.

Mathematical Recurrence / Code Invariant
lo, hi = 0, len(items) - 1
Core Invariant Specification & Code Shape
Archetype Code Shape
Python
1if not node: return 0
2left = height(node.left)
3right = height(node.right)
4diameter = max(diameter, left + right)
5return 1 + max(left, right)

Target: Diameter of Binary Tree (LeetCode 543). An empty subtree has height 0

Boundary Model: Depth-First Recursion / Call Stack Frame Lifecycle

Subtree bottom-up aggregation: a node combines child subtree solutions upon backtrack; top-down invariants pass accumulated state down the path.

Loop Invariant Termination

Base case: if not node: return base; recursive calls on left/right child nodes.

Conceptual Narrative

🧠 Pattern Intuition & Real-World Analogy

Maximum Depth (§4.1) returns one number per subtree. Diameter keeps that exact return value but asks a second question at every node: "if the longest path bent right here, how long would it be?" The return value and the answer are different quantities, which is why the answer lives in a separate global variable.

📏 The Analogy: Measuring the Widest Span of a River Delta

A surveyor maps a river delta that splits into channels like a tree. At every fork they ask the two branches below, "how far do you reach downstream?" The widest span through this fork is the left reach plus the right reach, and the surveyor notes it if it beats the record. But when reporting upward to the next fork, a channel can only continue in one direction, so the fork reports just its longer reach plus the one step up to its parent.

🪄 Breaking Down the Code's "Magic Trick"
Code / Blueprint
def height(node):
nonlocal diameter
if not node:
return 0
left = height(node.left)
right = height(node.right)
diameter = max(diameter, left + right) # the path that bends here, counted in edges
return 1 + max(left, right) # a parent can extend only one branch
 

The two lines after the recursive calls answer two different questions. left + right is the best path that bends at this node; it goes into the global record and is never returned. 1 + max(left, right) is the best path a parent could extend; it is returned and never recorded. Mixing them up is the whole bug class of this problem.

💡 Summary

When the answer is a path that may bend at any node, but a parent can only use a straight path from its child, return the straight-path value and record the bent-path value in a global. Every "longest path anywhere in the tree" problem uses this split.

  • Checking only the root's bend: Checking only the bend at the root misses a longer path that sits entirely inside one subtree ([1,2,null,3,4,5,null,null,6] has diameter 4, but the root's bend is only 3).

  • Counting nodes instead of edges: Counting nodes instead of edges is off by one on every input (a single node has diameter 0).

  • Returning the bent path upward: Returning left + right upward instead of 1 + max(left, right) hands the parent a path it cannot extend, because a parent can only continue down one branch.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

You will see why the value a node returns (its height) and the answer it records (the path bending at it) must be different quantities.

Pattern Recognition Signals

The 10-second spot

Longest path between any two nodes, measured in edges, not required to pass through the root.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: the longest path bending at a node has exactly height(left) + height(right) edges.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Only checking the root's bend: the longest path can sit entirely inside one subtree.

  • Counting nodes instead of edges: every answer is off by one.

  • Returning left + right upward: a parent cannot extend a path that already bends.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I write height(node) returning 0 for None. For a real node I get the left and right heights, update a global diameter with left + right, which is the number of edges on the path that bends here, and return 1 + max(left, right). After one call on the root the global holds the answer. That's O(N) time and O(H) stack space.

So: diameter = max(diameter, left + right); return 1 + max(left, right).

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the recursive function: `def maxDepth(node):`. For every node in the binary tree, the function executes exactly 2 recursive calls (`maxDepth(node.left)` and `maxDepth(node.right)`) and performs O(1) constant-time arithmetic combining their results (`1 + max(left, right)`). Because each of the N tree nodes is visited and processed exactly once, total time is N · O(1) = O(N).

SPACE COMPLEXITY

O(H) Auxiliary

Look at the recursion call stack: Each recursive call adds a new stack frame storing the local `node` pointer. The maximum number of simultaneous stack frames alive at any instant equals the maximum path depth from root to leaf, which is the tree height H. In a balanced binary tree, H = log2(N) -> O(log N) stack memory. In a worst-case skewed tree (linked list), H = N -> O(N) stack memory. We allocate zero heap objects, so auxiliary space is bounded by tree height O(H).

Formal Recurrence Relation

T(N) = 2T(N/2) + O(1) ⟹ O(N)

Look at the recursive function: def maxDepth(node):. For every node in the binary tree, the function executes exactly 2 recursive calls (maxDepth(node.left) and maxDepth(node.right)) and performs O(1) constant-time arithmetic combining their results (1 + max(left, right)). Because each of the N tree nodes is visited and processed exactly once, total time is N · O(1) = O(N).

Derivation Progression

Node Visitation

N nodes visited

Every node in the binary tree is entered and exited exactly once.

O(1) Work Per Frame

1 + max(left, right)

Combining child subproblem depths requires a single addition and max comparison in O(1).

Tree Recurrence

T(N) = 2T(N/2) + O(1) ⟹ O(N)

Visiting all N nodes with constant combining work yields strictly O(N) time.

Variable Definitions

NNN

Total number of nodes in the binary tree

HHH

Tree height (log N in balanced tree, N in skewed tree)

Memory Architecture & Bounds

🟣 Call Stack

O(H) Recursion stack storing tree height H frames (O(log N) balanced, O(N) skewed)

🔵 Auxiliary Heap

O(1) Zero heap allocations

🟢 Output Space

O(1) Returns integer tree depth

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N) time with O(log⁡N)O(\log N)O(logN) stack on balanced tree.

Average Case

O(N)O(N)O(N) time with O(log⁡N)O(\log N)O(logN) stack.

Worst Case

O(N)O(N)O(N) time with O(N)O(N)O(N) stack on skewed tree (linked list shape).

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: **"longest path between any two nodes"**, **"may or may not pass through the root"**, **"number of edges"**. Bottom-up height return with a global answer: each node returns its height, and separately updates a global best with the path that bends at it.

CONSTRAINTS & BOUNDS

N≤104N \le 10^4N≤104. One postorder pass: O(N)O(N)O(N) time.

FAANG PRODUCTION TRAPS & EDGE CASES

Checking only the bend at the root misses a longer path that sits entirely inside one subtree ([1,2,null,3,4,5,null,null,6] has diameter 4, but the root's bend is only 3). Counting nodes instead of edges is off by one on every input (a single node has diameter 0). Returning left + right upward instead of 1 + max(left, right) hands the parent a path it cannot extend, because a parent can only continue down one branch.

Core Algorithmic State Invariants

1. Subtree Independence Invariant

Each recursive invocation evaluates disjoint subtrees independently, synthesizing solutions bottom-up from child return values without cross-branch interference.

2. Post-Order Composition Invariant

Node state is computed from child results (e.g. 1 + max(L, R) for height, or sentinel -1 when balanced condition |L - R| <= 1 fails), bubbling answers toward the root.

3. Base Case Identity Termination

Null nodes return mathematical identity values (0 for height/count, True for balance, None for LCA), guaranteeing clean recursion termination in O(H) stack space.

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

Diameter of Binary Tree (LeetCode 543)

Height Return + Global Extremum: The Longest Path May Bend at Any Node

Target Frequency:MetaAmazonGoogleMicrosoft

You are given the root of a binary tree. The diameter is the length of the longest path between any two nodes, measured as the number of edges on that path. The path does not have to pass through the root. Return the diameter.

Worked Examples

Example 1
Input:root = [1,2,3,4,5]
Output:3
Explanation: The path 4 -> 2 -> 1 -> 3 (or 5 -> 2 -> 1 -> 3) has 3 edges, and no path is longer.
Example 2
Input:root = [1,2]
Output:1
Explanation: The only path joins the two nodes with a single edge.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [1, 104].

  • -100 <= Node.val <= 100

Deep-Dive & Conceptual Insights

Why It Works & Core Invariant

Every path has one highest node where it bends. At each node, the longest path bending there has height(left) + height(right) edges. Record that in a global, but return only 1 + max(left, right), because a parent can extend just one straight branch.

Real-World Scenario & Production Applications

Worst-case hop count between two devices in a tree-shaped network, the longest chain between any two people in an org chart, the widest span of a river delta.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Boundary & State Setup

Establish initial problem boundaries and state invariants such that the valid search space is fully bounded.

Mathematical Recurrence / Code Invariant
lo, hi = 0, len(items) - 1
Core Invariant Specification & Code Shape
Archetype Code Shape
Python
1if not node: return 0
2left = height(node.left)
3right = height(node.right)
4diameter = max(diameter, left + right)
5return 1 + max(left, right)

Target: Diameter of Binary Tree (LeetCode 543). An empty subtree has height 0

Boundary Model: Depth-First Recursion / Call Stack Frame Lifecycle

Subtree bottom-up aggregation: a node combines child subtree solutions upon backtrack; top-down invariants pass accumulated state down the path.

Loop Invariant Termination

Base case: if not node: return base; recursive calls on left/right child nodes.

Conceptual Narrative

🧠 Pattern Intuition & Real-World Analogy

Maximum Depth (§4.1) returns one number per subtree. Diameter keeps that exact return value but asks a second question at every node: "if the longest path bent right here, how long would it be?" The return value and the answer are different quantities, which is why the answer lives in a separate global variable.

📏 The Analogy: Measuring the Widest Span of a River Delta

A surveyor maps a river delta that splits into channels like a tree. At every fork they ask the two branches below, "how far do you reach downstream?" The widest span through this fork is the left reach plus the right reach, and the surveyor notes it if it beats the record. But when reporting upward to the next fork, a channel can only continue in one direction, so the fork reports just its longer reach plus the one step up to its parent.

🪄 Breaking Down the Code's "Magic Trick"
Code / Blueprint
def height(node):
nonlocal diameter
if not node:
return 0
left = height(node.left)
right = height(node.right)
diameter = max(diameter, left + right) # the path that bends here, counted in edges
return 1 + max(left, right) # a parent can extend only one branch
 

The two lines after the recursive calls answer two different questions. left + right is the best path that bends at this node; it goes into the global record and is never returned. 1 + max(left, right) is the best path a parent could extend; it is returned and never recorded. Mixing them up is the whole bug class of this problem.

💡 Summary

When the answer is a path that may bend at any node, but a parent can only use a straight path from its child, return the straight-path value and record the bent-path value in a global. Every "longest path anywhere in the tree" problem uses this split.

  • Checking only the root's bend: Checking only the bend at the root misses a longer path that sits entirely inside one subtree ([1,2,null,3,4,5,null,null,6] has diameter 4, but the root's bend is only 3).

  • Counting nodes instead of edges: Counting nodes instead of edges is off by one on every input (a single node has diameter 0).

  • Returning the bent path upward: Returning left + right upward instead of 1 + max(left, right) hands the parent a path it cannot extend, because a parent can only continue down one branch.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

You will see why the value a node returns (its height) and the answer it records (the path bending at it) must be different quantities.

Pattern Recognition Signals

The 10-second spot

Longest path between any two nodes, measured in edges, not required to pass through the root.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: the longest path bending at a node has exactly height(left) + height(right) edges.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Only checking the root's bend: the longest path can sit entirely inside one subtree.

  • Counting nodes instead of edges: every answer is off by one.

  • Returning left + right upward: a parent cannot extend a path that already bends.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I write height(node) returning 0 for None. For a real node I get the left and right heights, update a global diameter with left + right, which is the number of edges on the path that bends here, and return 1 + max(left, right). After one call on the root the global holds the answer. That's O(N) time and O(H) stack space.

So: diameter = max(diameter, left + right); return 1 + max(left, right).

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the recursive function: `def maxDepth(node):`. For every node in the binary tree, the function executes exactly 2 recursive calls (`maxDepth(node.left)` and `maxDepth(node.right)`) and performs O(1) constant-time arithmetic combining their results (`1 + max(left, right)`). Because each of the N tree nodes is visited and processed exactly once, total time is N · O(1) = O(N).

SPACE COMPLEXITY

O(H) Auxiliary

Look at the recursion call stack: Each recursive call adds a new stack frame storing the local `node` pointer. The maximum number of simultaneous stack frames alive at any instant equals the maximum path depth from root to leaf, which is the tree height H. In a balanced binary tree, H = log2(N) -> O(log N) stack memory. In a worst-case skewed tree (linked list), H = N -> O(N) stack memory. We allocate zero heap objects, so auxiliary space is bounded by tree height O(H).

Formal Recurrence Relation

T(N) = 2T(N/2) + O(1) ⟹ O(N)

Look at the recursive function: def maxDepth(node):. For every node in the binary tree, the function executes exactly 2 recursive calls (maxDepth(node.left) and maxDepth(node.right)) and performs O(1) constant-time arithmetic combining their results (1 + max(left, right)). Because each of the N tree nodes is visited and processed exactly once, total time is N · O(1) = O(N).

Derivation Progression

Node Visitation

N nodes visited

Every node in the binary tree is entered and exited exactly once.

O(1) Work Per Frame

1 + max(left, right)

Combining child subproblem depths requires a single addition and max comparison in O(1).

Tree Recurrence

T(N) = 2T(N/2) + O(1) ⟹ O(N)

Visiting all N nodes with constant combining work yields strictly O(N) time.

Variable Definitions

NNN

Total number of nodes in the binary tree

HHH

Tree height (log N in balanced tree, N in skewed tree)

Memory Architecture & Bounds

🟣 Call Stack

O(H) Recursion stack storing tree height H frames (O(log N) balanced, O(N) skewed)

🔵 Auxiliary Heap

O(1) Zero heap allocations

🟢 Output Space

O(1) Returns integer tree depth

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N) time with O(log⁡N)O(\log N)O(logN) stack on balanced tree.

Average Case

O(N)O(N)O(N) time with O(log⁡N)O(\log N)O(logN) stack.

Worst Case

O(N)O(N)O(N) time with O(N)O(N)O(N) stack on skewed tree (linked list shape).

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: **"longest path between any two nodes"**, **"may or may not pass through the root"**, **"number of edges"**. Bottom-up height return with a global answer: each node returns its height, and separately updates a global best with the path that bends at it.

CONSTRAINTS & BOUNDS

N≤104N \le 10^4N≤104. One postorder pass: O(N)O(N)O(N) time.

FAANG PRODUCTION TRAPS & EDGE CASES

Checking only the bend at the root misses a longer path that sits entirely inside one subtree ([1,2,null,3,4,5,null,null,6] has diameter 4, but the root's bend is only 3). Counting nodes instead of edges is off by one on every input (a single node has diameter 0). Returning left + right upward instead of 1 + max(left, right) hands the parent a path it cannot extend, because a parent can only continue down one branch.

Core Algorithmic State Invariants

1. Subtree Independence Invariant

Each recursive invocation evaluates disjoint subtrees independently, synthesizing solutions bottom-up from child return values without cross-branch interference.

2. Post-Order Composition Invariant

Node state is computed from child results (e.g. 1 + max(L, R) for height, or sentinel -1 when balanced condition |L - R| <= 1 fails), bubbling answers toward the root.

3. Base Case Identity Termination

Null nodes return mathematical identity values (0 for height/count, True for balance, None for LCA), guaranteeing clean recursion termination in O(H) stack space.

Rosetta Dual-Monaco ComparisonPython 3
CANONICAL INVARIANT TEMPLATE
Loading...
CONCRETE: DIAMETER OF BINARY TREE (LEETCODE 543)
T = O(N)S = O(H) Auxiliary
Loading...
Pattern Implementation Mapping TableCanonical Invariant ⟷ Concrete Code ⟷ Engineering Rationale
Canonical InvariantConcrete CodeEngineering Rationale
if node is None: return 0if not node: return 0An empty subtree has height 0
left_h = dfs_height_with_global(node.left, best); right_h = dfs_height_with_global(node.right, best)left = height(node.left); right = height(node.right)Postorder: both heights are known before combining
best[0] = max(best[0], left_h + right_h)diameter = max(diameter, left + right)The bent path at this node, in edges, is recorded but never returned
return 1 + max(left_h, right_h)return 1 + max(left, right)A parent can extend only the longer straight branch
© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•