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)
MediumLC 98

Validate Binary Search Tree (LeetCode 98)

Target Frequency:AmazonMetaGoogleApple

You're handed the root of a binary tree and must judge whether it is a legitimate binary search tree (BST).

A tree only counts as a valid BST when, at every node:

  • everything in its left subtree is strictly smaller than the node's own key,
  • everything in its right subtree is strictly larger than the node's own key, and
  • both of those subtrees are themselves valid BSTs.

Worked Examples

Example 1
Input:root = [2,1,3]
Output:true
123
Explanation: 1 sits left of 2 and is smaller; 3 sits right of 2 and is larger.
Example 2
Input:root = [5,1,4,null,null,3,6]
Output:false
15346
Explanation: The root is 5, but its right child is 4. Everything in the right subtree must be greater than 5, so the tree is not a valid BST.

⚖️Formal Constraints & Bounds

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

  • -231 <= Node.val <= 231 - 1

Deep-Dive & Conceptual Insights

Core Insight

Narrowing valid range bounds during recursion ensures ancestor constraints are never violated.

Real-World Scenario & Production Applications

B-Tree database index invariant verification, sorted symbol table integrity checking.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Monotonic Range Invariant

A valid BST requires every node value to satisfy strict open bounds: low < node.val < high. Root starts with (-inf, +inf).

Mathematical Recurrence / Code Invariant
def validate(node, low, high):
    if not node:
        return True
    if not (low < node.val < high):
        return False

Step-by-Step Execution Trace Table

NodeValid Interval (low, high)Node.val in Interval?Decision
2 (root)(-inf, +inf)-inf < 2 < +inf (True)Valid
1 (left)(-inf, 2)-inf < 1 < 2 (True)Valid
3 (right)(2, +inf)2 < 3 < +inf (True)Valid BST
Trace Inputroot = [2,1,3]
Expectedtrue
NodeValid Interval (low, high)Node.val in Interval?Decision
2 (root)(-inf, +inf)-inf < 2 < +inf (True)Valid
1 (left)(-inf, 2)-inf < 1 < 2 (True)Valid
3 (right)(2, +inf)2 < 3 < +inf (True)Valid BST
Code Shape
Archetype Code Shape
Python
1def validate(node, low, high):
2 if not node:
3 return True
4 if not (low < node.val < high):
5 return False
6 return validate(node.left, low, node.val) and validate(node.right, node.val, high)
7return validate(root, float('-inf'), float('inf'))

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

"Just check that each node is bigger than its left child and smaller than its right child" is the tempting shortcut — and it's wrong. A node can look locally fine while still violating the BST property against an ancestor several levels up.

📜 The Analogy: A Contract That Gets Narrower With Every Signature

Imagine a legal contract that starts with an unlimited range: "your value can be anything." As it's handed down from the root, every time you step left, the contract gets a new upper limit (this branch must stay below the parent). Every time you step right, it gets a new lower limit (this branch must stay above the parent). By the time the contract reaches a deep node, it's been narrowed by every single ancestor along the way, not just the immediate parent — so a node's real obligation is "obey every constraint every ancestor imposed," not merely "obey your parent."

🔑 The Key Idea in the Code

The left recursive call tightens the upper bound to the current node's value; the right call tightens the lower bound. Each call receives the cumulative range every ancestor has already narrowed — which is exactly why a single local comparison (child vs. immediate parent) isn't enough, but this open-interval range is.

  • Local child comparison trap: Only verifying node.left.val < node.val < node.right.val locally. A node in the right subtree could be smaller than the root ancestor! Pass bounding intervals (low, high) down the recursion.

  • Strict inequality violation: BST definition requires strictly less than and strictly greater than. Allowing node.val == low or node.val == high permits invalid duplicates in standard BSTs.

  • Integer boundary overflow: Initializing low = -231 and high = 231 - 1 fails when node values equal INT_MIN or INT_MAX. Use float('-inf') and float('inf').

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Binary search tree validation requiring strict global subtree ordering.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: every node in the current subtree must satisfy low < node.val < high.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: if not (low < node.val < high) checks the window from every ancestor; checking only left.val < node.val < right.val accepts [5, 4, 6, null, null, 3, 7], where the 3 under the 6 breaks the root's rule.

  • Computing both sides before combining (left_ok = validate(...), right_ok = validate(...), then return left_ok and right_ok) still walks the whole right subtree after the left side has failed. return validate(node.left, low, node.val) and validate(node.right, node.val, high) stops at the first broken bound.

  • Treating an empty subtree as a failure: None is a valid BST, so the base case returns True; returning False there rejects every tree that has a leaf.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'll use BST Bounds. The BST rule covers whole subtrees, so each node must fit between bounds set by every ancestor, not just its parent. I carry an open window (low, high) down from (-inf, inf): going left caps high at node.val, going right raises low to node.val, and each node checks low < node.val < high, strictly, so duplicates fail. The trap is checking only children: in [5, 4, 6, null, null, 3, 7] every parent and child pair looks fine, but 3 sits in 5's right subtree. Each node is checked once, so O(N) time, and the recursion is O(H) deep."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the execution steps: DFS passes the valid range (low, high) to each child. At each node, checks low < node.val < high in O(1) time. Each node visited once.

SPACE COMPLEXITY

O(H) Auxiliary

Recursion stack depth equals tree height H.

Formal Recurrence Relation

T(N) = O(N)

Derivation Progression

Range Shrinkage

(L, node.val) for left, (node.val, R) for right

Tightens valid numeric bounds for each subtree.

Validity Invariant Check

L < node.val < R

Verifies BST property in constant time.

Single Pass

N node evaluations

Validates tree in linear 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) Call stack depth (log N to N)

🔵 Auxiliary Heap

O(1) Zero heap allocations

🟢 Output Space

O(1) Boolean return

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1) on early invalid root/child violation.

Average Case

O(N)O(N)O(N).

Worst Case

O(N)O(N)O(N) on valid BST.

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: "validate binary search tree", "strictly less than / greater than". The BST rule is about whole subtrees, not pairs of nodes, so each node inherits limits from every ancestor on its path: BST Bounds, an open window (low,high)(low, high)(low,high) carried down, with every node satisfying low<node.val<highlow < node.val < highlow<node.val<high.

CONSTRAINTS & BOUNDS

N≤104N \le 10^4N≤104, −231≤node.val≤231−1-2^{31} \le node.val \le 2^{31}-1−231≤node.val≤231−1. Time budget is O(N)O(N)O(N) linear time.

FAANG PRODUCTION TRAPS & EDGE CASES

At scale the risk is depth, not the comparison: inserting keys in sorted order builds a chain, and a 10410^4104-node chain is 10410^4104 nested validate calls, past CPython's default recursion limit of 1000. Production code raises the limit or walks with an explicit stack of (node, low, high) entries, which keeps the same window per node.

Theory Context•Depth-First Search (DFS)
MediumLC 98

Validate Binary Search Tree (LeetCode 98)

Target Frequency:AmazonMetaGoogleApple

You're handed the root of a binary tree and must judge whether it is a legitimate binary search tree (BST).

A tree only counts as a valid BST when, at every node:

  • everything in its left subtree is strictly smaller than the node's own key,
  • everything in its right subtree is strictly larger than the node's own key, and
  • both of those subtrees are themselves valid BSTs.

Worked Examples

Example 1
Input:root = [2,1,3]
Output:true
123
Explanation: 1 sits left of 2 and is smaller; 3 sits right of 2 and is larger.
Example 2
Input:root = [5,1,4,null,null,3,6]
Output:false
15346
Explanation: The root is 5, but its right child is 4. Everything in the right subtree must be greater than 5, so the tree is not a valid BST.

⚖️Formal Constraints & Bounds

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

  • -231 <= Node.val <= 231 - 1

Deep-Dive & Conceptual Insights

Core Insight

Narrowing valid range bounds during recursion ensures ancestor constraints are never violated.

Real-World Scenario & Production Applications

B-Tree database index invariant verification, sorted symbol table integrity checking.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Monotonic Range Invariant

A valid BST requires every node value to satisfy strict open bounds: low < node.val < high. Root starts with (-inf, +inf).

Mathematical Recurrence / Code Invariant
def validate(node, low, high):
    if not node:
        return True
    if not (low < node.val < high):
        return False

Step-by-Step Execution Trace Table

NodeValid Interval (low, high)Node.val in Interval?Decision
2 (root)(-inf, +inf)-inf < 2 < +inf (True)Valid
1 (left)(-inf, 2)-inf < 1 < 2 (True)Valid
3 (right)(2, +inf)2 < 3 < +inf (True)Valid BST
Trace Inputroot = [2,1,3]
Expectedtrue
NodeValid Interval (low, high)Node.val in Interval?Decision
2 (root)(-inf, +inf)-inf < 2 < +inf (True)Valid
1 (left)(-inf, 2)-inf < 1 < 2 (True)Valid
3 (right)(2, +inf)2 < 3 < +inf (True)Valid BST
Code Shape
Archetype Code Shape
Python
1def validate(node, low, high):
2 if not node:
3 return True
4 if not (low < node.val < high):
5 return False
6 return validate(node.left, low, node.val) and validate(node.right, node.val, high)
7return validate(root, float('-inf'), float('inf'))

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

"Just check that each node is bigger than its left child and smaller than its right child" is the tempting shortcut — and it's wrong. A node can look locally fine while still violating the BST property against an ancestor several levels up.

📜 The Analogy: A Contract That Gets Narrower With Every Signature

Imagine a legal contract that starts with an unlimited range: "your value can be anything." As it's handed down from the root, every time you step left, the contract gets a new upper limit (this branch must stay below the parent). Every time you step right, it gets a new lower limit (this branch must stay above the parent). By the time the contract reaches a deep node, it's been narrowed by every single ancestor along the way, not just the immediate parent — so a node's real obligation is "obey every constraint every ancestor imposed," not merely "obey your parent."

🔑 The Key Idea in the Code

The left recursive call tightens the upper bound to the current node's value; the right call tightens the lower bound. Each call receives the cumulative range every ancestor has already narrowed — which is exactly why a single local comparison (child vs. immediate parent) isn't enough, but this open-interval range is.

  • Local child comparison trap: Only verifying node.left.val < node.val < node.right.val locally. A node in the right subtree could be smaller than the root ancestor! Pass bounding intervals (low, high) down the recursion.

  • Strict inequality violation: BST definition requires strictly less than and strictly greater than. Allowing node.val == low or node.val == high permits invalid duplicates in standard BSTs.

  • Integer boundary overflow: Initializing low = -231 and high = 231 - 1 fails when node values equal INT_MIN or INT_MAX. Use float('-inf') and float('inf').

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Binary search tree validation requiring strict global subtree ordering.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: every node in the current subtree must satisfy low < node.val < high.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: if not (low < node.val < high) checks the window from every ancestor; checking only left.val < node.val < right.val accepts [5, 4, 6, null, null, 3, 7], where the 3 under the 6 breaks the root's rule.

  • Computing both sides before combining (left_ok = validate(...), right_ok = validate(...), then return left_ok and right_ok) still walks the whole right subtree after the left side has failed. return validate(node.left, low, node.val) and validate(node.right, node.val, high) stops at the first broken bound.

  • Treating an empty subtree as a failure: None is a valid BST, so the base case returns True; returning False there rejects every tree that has a leaf.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'll use BST Bounds. The BST rule covers whole subtrees, so each node must fit between bounds set by every ancestor, not just its parent. I carry an open window (low, high) down from (-inf, inf): going left caps high at node.val, going right raises low to node.val, and each node checks low < node.val < high, strictly, so duplicates fail. The trap is checking only children: in [5, 4, 6, null, null, 3, 7] every parent and child pair looks fine, but 3 sits in 5's right subtree. Each node is checked once, so O(N) time, and the recursion is O(H) deep."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the execution steps: DFS passes the valid range (low, high) to each child. At each node, checks low < node.val < high in O(1) time. Each node visited once.

SPACE COMPLEXITY

O(H) Auxiliary

Recursion stack depth equals tree height H.

Formal Recurrence Relation

T(N) = O(N)

Derivation Progression

Range Shrinkage

(L, node.val) for left, (node.val, R) for right

Tightens valid numeric bounds for each subtree.

Validity Invariant Check

L < node.val < R

Verifies BST property in constant time.

Single Pass

N node evaluations

Validates tree in linear 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) Call stack depth (log N to N)

🔵 Auxiliary Heap

O(1) Zero heap allocations

🟢 Output Space

O(1) Boolean return

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1) on early invalid root/child violation.

Average Case

O(N)O(N)O(N).

Worst Case

O(N)O(N)O(N) on valid BST.

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: "validate binary search tree", "strictly less than / greater than". The BST rule is about whole subtrees, not pairs of nodes, so each node inherits limits from every ancestor on its path: BST Bounds, an open window (low,high)(low, high)(low,high) carried down, with every node satisfying low<node.val<highlow < node.val < highlow<node.val<high.

CONSTRAINTS & BOUNDS

N≤104N \le 10^4N≤104, −231≤node.val≤231−1-2^{31} \le node.val \le 2^{31}-1−231≤node.val≤231−1. Time budget is O(N)O(N)O(N) linear time.

FAANG PRODUCTION TRAPS & EDGE CASES

At scale the risk is depth, not the comparison: inserting keys in sorted order builds a chain, and a 10410^4104-node chain is 10410^4104 nested validate calls, past CPython's default recursion limit of 1000. Production code raises the limit or walks with an explicit stack of (node, low, high) entries, which keeps the same window per node.

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