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 230

Kth Smallest Element in a BST (LeetCode 230)

Target Frequency:AmazonMetaGoogle

You get the root of a binary search tree and a whole number k. Imagine writing every value in the tree in a row, smallest first, and numbering the positions from 1: return the value that lands in position k.

In a binary search tree, the values in a node's left subtree are smaller than the node's value, and the values in its right subtree are larger.

Follow-up: if nodes are inserted and deleted often and this question is asked again and again, how would you make each answer faster?

Worked Examples

Example 1
Input:root = [3,1,4,null,2], k = 1
Output:1
1234
Explanation: Written smallest first, the values are 1, 2, 3, 4. Position 1 holds 1, a leaf on the left, even though 3 sits at the top of the tree.
Example 2
Input:root = [5,3,6,2,4,null,null,1], k = 3
Output:3
123456
Explanation: Written smallest first, the values are 1, 2, 3, 4, 5, 6, so position 3 holds 3.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is n.

  • 1 <= k <= n <= 104

  • 0 <= Node.val <= 104

Deep-Dive & Conceptual Insights

Core Insight

Rank in a BST is position in sorted order, and the inorder walk produces sorted order one value per visit, so the k-th visit is the answer and the walk can stop there.

Real-World Scenario & Production Applications

Rank queries on ordered data are everywhere: the 10th cheapest listing, the median of a set of latency samples, the k-th oldest open ticket. When the data already sits in a search tree it is sorted in place, so walking it in order and stopping at the k-th item beats copying everything out and sorting it again.

Step-by-Step Execution Trace Table

Example 2, root = [5,3,6,2,4,null,null,1], k = 3:

StepWhat runsstack (bottom to top)nodekWhat it means
1Dive: stack.append(node), node = node.left[5, 3, 2, 1]None3Four nodes pushed, none counted: pushing is not visiting
2node = stack.pop(), k -= 1[5, 3, 2]121st visit: 1 is the smallest value
3node = node.right is None; pop, k -= 1[5, 3]212nd visit
4node = node.right is None; pop, k -= 1[5]303rd visit: k == 0, return 3

Counting pushes instead would reach k == 0 at the third push, node 2, and return the wrong value.

Trace Inputroot = [3,1,4,null,2], k = 1
Expected1

Example 2, root = [5,3,6,2,4,null,null,1], k = 3:

StepWhat runsstack (bottom to top)nodekWhat it means
1Dive: stack.append(node), node = node.left[5, 3, 2, 1]None3Four nodes pushed, none counted: pushing is not visiting
2node = stack.pop(), k -= 1[5, 3, 2]121st visit: 1 is the smallest value
3node = node.right is None; pop, k -= 1[5, 3]212nd visit
4node = node.right is None; pop, k -= 1[5]303rd visit: k == 0, return 3

Counting pushes instead would reach k == 0 at the third push, node 2, and return the wrong value.

Code Shape
Archetype Code Shape
Python
1Rank in a BST is position in sorted order, and an inorder walk (left subtree, node, right subtree) visits the values in sorted order: the answer is the `k`-th visit.
2When `stack.pop()` returns `node`, every smaller value has already been visited, so do `k -= 1` there and `return node.val` when `k == 0`.
3Start with `stack = []` and `node = root`, and loop `while node or stack`: an inner `while node` pushes and moves to `node.left`, then pop, count, and move to `node.right`.
4The trap: count on the pop, never on the push. Nodes are pushed from the root down, so counting pushes on `[3,1,4,null,2]` returns 3 for `k = 1`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

The k-th smallest value sounds like a job for sorting: copy every value out, sort, and index. A BST makes that unnecessary, because it is already sorted, just not in a line. Every value in a node's left subtree is smaller than the node, and every value in its right subtree is larger, so the order left subtree, node, right subtree (an inorder walk) visits the values from smallest to largest. BST Inorder reads the tree as that sorted list, one value per visit, and stops as soon as it has what it needs.

📚 The Analogy: A Library Shelved by Call Number

A library keeps its books in call-number order along branching aisles: every aisle to your left holds smaller numbers, every aisle to your right larger ones. To find the 10th book in call-number order, you don't pull every book off the shelves and sort them. You walk to the far left end, then walk the aisles in order, counting books as you pass them, and stop at the 10th. On the way in you note each turn you skipped (the stack), so you can come back to it.

🔑 Why It Works

The inner loop dives left, pushing every node it passes, so the node that stack.pop() returns has no smaller value left unvisited: its left subtree is done, and so is every ancestor it sits to the right of. Each pop is therefore the next value in sorted order, and k -= 1 on the pop counts ranks exactly. Counting on the push instead would count nodes from the root down, which is not sorted order.

  • Counting k -= 1 when a node is pushed

  • Looping while stack instead of while node or stack

  • Pushing node.right straight onto stack

  • Walking every node when the nearest values are already found

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Binary search tree" plus "the k-th smallest value": rank means position in sorted order, and in a BST the inorder walk (left subtree, node, right subtree) already produces sorted order. When a BST question is about ranks, neighbouring values or the values nearest a target, that is the signal for BST Inorder.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

The decision is made at each pop: k -= 1, and if k == 0, node.val is the answer; otherwise node = node.right and the walk goes on. k always counts the visits still needed.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: count on the pop (k -= 1 after stack.pop()), not on the push.

  • k is 1-indexed: run k -= 1 before the k == 0 test. Testing first returns the (k + 1)-th smallest value.

  • Return inside the loop at k == 0. Finishing the walk and remembering the k-th value is still correct, but it visits all n nodes instead of stopping after k.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use BST Inorder. In a binary search tree, visiting the left subtree, then the node, then the right subtree hands out the values in sorted order, so the k-th smallest is simply the k-th visit. I walk iteratively with a stack: going left, I push every node I pass, so when I pop a node, everything smaller than it has already been visited. On each pop I decrement k, and when k reaches zero I return that node's value; otherwise I continue from its right child. The trap is where I count: nodes are pushed from the root down, so counting pushes would return a value near the root instead of the k-th smallest. Counting pops keeps the count equal to the rank. I stop after k visits, so the time is O(H plus k), where H is the height of the tree, and the stack uses O(H) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(H + k)

Look at the code: before the first visit, the inner while node: loop pushes the left edge of the tree, at most H nodes. After that, each pass of the outer loop visits one node with stack.pop() and k -= 1, and every node pushed along the way is either visited later or still on stack when the function returns. The walk returns at the k-th visit, so it makes at most k pops and at most H + k pushes, each O(1). Total: O(H + k).

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. The answer is one integer.

Formal Recurrence Relation

T(n)=O(H)+k⋅O(1)=O(H+k)T(n) = O(H) + k \cdot O(1) = O(H + k)T(n)=O(H)+k⋅O(1)=O(H+k)

Derivation Progression

First dive

at most H pushes

Before the first visit, while node: pushes the left edge of the tree, one node per level.

Visits

k pops

Each pass of while node or stack: pops one node and runs k -= 1; the function returns at the k-th pop.

Pushes after the first dive

at most H + k pushes in total

Every pushed node is either popped (at most k of them) or still on stack at the return (at most H).

Total

O(H + k)

Each push and pop is O(1).

Variable Definitions

nnn

Number of nodes in the tree

HHH

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

kkk

The rank asked for, 1 <= k <= n

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(1): one integer

Boundary Best / Worst Cases

Best Case

O(H)O(H)O(H): k = 1, one dive down the left edge and a single visit

Average Case

O(log⁡n+k)O(\log n + k)O(logn+k) on a balanced tree

Worst Case

O(n)O(n)O(n): k = n, or a chain of height nnn

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: "binary search tree", "the k-th smallest value". A rank question on a BST: BST Inorder, read as a stream that stops after k visits.

CONSTRAINTS & BOUNDS

n≤104n \le 10^4n≤104 nodes, 1≤k≤n1 \le k \le n1≤k≤n. Copying every value into a list and sorting costs O(nlog⁡n)O(n \log n)O(nlogn) time and O(n)O(n)O(n) memory; the iterative walk stops after k visits, so it costs O(H+k)O(H + k)O(H+k) time and only the O(H)O(H)O(H) stack, where HHH is the tree height (log⁡n\log nlogn when balanced, up to nnn on a chain).

FAANG PRODUCTION TRAPS & EDGE CASES

A chain of 10410^4104 nodes is 10410^4104 levels deep: a recursive walk can overflow a small call stack, and the explicit stack avoids that. LeetCode's follow-up (many queries while nodes are inserted and deleted) calls for storing each node's subtree size, so one query walks a single root-to-leaf path in O(H)O(H)O(H).

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

Kth Smallest Element in a BST (LeetCode 230)

Target Frequency:AmazonMetaGoogle

You get the root of a binary search tree and a whole number k. Imagine writing every value in the tree in a row, smallest first, and numbering the positions from 1: return the value that lands in position k.

In a binary search tree, the values in a node's left subtree are smaller than the node's value, and the values in its right subtree are larger.

Follow-up: if nodes are inserted and deleted often and this question is asked again and again, how would you make each answer faster?

Worked Examples

Example 1
Input:root = [3,1,4,null,2], k = 1
Output:1
1234
Explanation: Written smallest first, the values are 1, 2, 3, 4. Position 1 holds 1, a leaf on the left, even though 3 sits at the top of the tree.
Example 2
Input:root = [5,3,6,2,4,null,null,1], k = 3
Output:3
123456
Explanation: Written smallest first, the values are 1, 2, 3, 4, 5, 6, so position 3 holds 3.

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is n.

  • 1 <= k <= n <= 104

  • 0 <= Node.val <= 104

Deep-Dive & Conceptual Insights

Core Insight

Rank in a BST is position in sorted order, and the inorder walk produces sorted order one value per visit, so the k-th visit is the answer and the walk can stop there.

Real-World Scenario & Production Applications

Rank queries on ordered data are everywhere: the 10th cheapest listing, the median of a set of latency samples, the k-th oldest open ticket. When the data already sits in a search tree it is sorted in place, so walking it in order and stopping at the k-th item beats copying everything out and sorting it again.

Step-by-Step Execution Trace Table

Example 2, root = [5,3,6,2,4,null,null,1], k = 3:

StepWhat runsstack (bottom to top)nodekWhat it means
1Dive: stack.append(node), node = node.left[5, 3, 2, 1]None3Four nodes pushed, none counted: pushing is not visiting
2node = stack.pop(), k -= 1[5, 3, 2]121st visit: 1 is the smallest value
3node = node.right is None; pop, k -= 1[5, 3]212nd visit
4node = node.right is None; pop, k -= 1[5]303rd visit: k == 0, return 3

Counting pushes instead would reach k == 0 at the third push, node 2, and return the wrong value.

Trace Inputroot = [3,1,4,null,2], k = 1
Expected1

Example 2, root = [5,3,6,2,4,null,null,1], k = 3:

StepWhat runsstack (bottom to top)nodekWhat it means
1Dive: stack.append(node), node = node.left[5, 3, 2, 1]None3Four nodes pushed, none counted: pushing is not visiting
2node = stack.pop(), k -= 1[5, 3, 2]121st visit: 1 is the smallest value
3node = node.right is None; pop, k -= 1[5, 3]212nd visit
4node = node.right is None; pop, k -= 1[5]303rd visit: k == 0, return 3

Counting pushes instead would reach k == 0 at the third push, node 2, and return the wrong value.

Code Shape
Archetype Code Shape
Python
1Rank in a BST is position in sorted order, and an inorder walk (left subtree, node, right subtree) visits the values in sorted order: the answer is the `k`-th visit.
2When `stack.pop()` returns `node`, every smaller value has already been visited, so do `k -= 1` there and `return node.val` when `k == 0`.
3Start with `stack = []` and `node = root`, and loop `while node or stack`: an inner `while node` pushes and moves to `node.left`, then pop, count, and move to `node.right`.
4The trap: count on the pop, never on the push. Nodes are pushed from the root down, so counting pushes on `[3,1,4,null,2]` returns 3 for `k = 1`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

The k-th smallest value sounds like a job for sorting: copy every value out, sort, and index. A BST makes that unnecessary, because it is already sorted, just not in a line. Every value in a node's left subtree is smaller than the node, and every value in its right subtree is larger, so the order left subtree, node, right subtree (an inorder walk) visits the values from smallest to largest. BST Inorder reads the tree as that sorted list, one value per visit, and stops as soon as it has what it needs.

📚 The Analogy: A Library Shelved by Call Number

A library keeps its books in call-number order along branching aisles: every aisle to your left holds smaller numbers, every aisle to your right larger ones. To find the 10th book in call-number order, you don't pull every book off the shelves and sort them. You walk to the far left end, then walk the aisles in order, counting books as you pass them, and stop at the 10th. On the way in you note each turn you skipped (the stack), so you can come back to it.

🔑 Why It Works

The inner loop dives left, pushing every node it passes, so the node that stack.pop() returns has no smaller value left unvisited: its left subtree is done, and so is every ancestor it sits to the right of. Each pop is therefore the next value in sorted order, and k -= 1 on the pop counts ranks exactly. Counting on the push instead would count nodes from the root down, which is not sorted order.

  • Counting k -= 1 when a node is pushed

  • Looping while stack instead of while node or stack

  • Pushing node.right straight onto stack

  • Walking every node when the nearest values are already found

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Binary search tree" plus "the k-th smallest value": rank means position in sorted order, and in a BST the inorder walk (left subtree, node, right subtree) already produces sorted order. When a BST question is about ranks, neighbouring values or the values nearest a target, that is the signal for BST Inorder.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

The decision is made at each pop: k -= 1, and if k == 0, node.val is the answer; otherwise node = node.right and the walk goes on. k always counts the visits still needed.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: count on the pop (k -= 1 after stack.pop()), not on the push.

  • k is 1-indexed: run k -= 1 before the k == 0 test. Testing first returns the (k + 1)-th smallest value.

  • Return inside the loop at k == 0. Finishing the walk and remembering the k-th value is still correct, but it visits all n nodes instead of stopping after k.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use BST Inorder. In a binary search tree, visiting the left subtree, then the node, then the right subtree hands out the values in sorted order, so the k-th smallest is simply the k-th visit. I walk iteratively with a stack: going left, I push every node I pass, so when I pop a node, everything smaller than it has already been visited. On each pop I decrement k, and when k reaches zero I return that node's value; otherwise I continue from its right child. The trap is where I count: nodes are pushed from the root down, so counting pushes would return a value near the root instead of the k-th smallest. Counting pops keeps the count equal to the rank. I stop after k visits, so the time is O(H plus k), where H is the height of the tree, and the stack uses O(H) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(H + k)

Look at the code: before the first visit, the inner while node: loop pushes the left edge of the tree, at most H nodes. After that, each pass of the outer loop visits one node with stack.pop() and k -= 1, and every node pushed along the way is either visited later or still on stack when the function returns. The walk returns at the k-th visit, so it makes at most k pops and at most H + k pushes, each O(1). Total: O(H + k).

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. The answer is one integer.

Formal Recurrence Relation

T(n)=O(H)+k⋅O(1)=O(H+k)T(n) = O(H) + k \cdot O(1) = O(H + k)T(n)=O(H)+k⋅O(1)=O(H+k)

Derivation Progression

First dive

at most H pushes

Before the first visit, while node: pushes the left edge of the tree, one node per level.

Visits

k pops

Each pass of while node or stack: pops one node and runs k -= 1; the function returns at the k-th pop.

Pushes after the first dive

at most H + k pushes in total

Every pushed node is either popped (at most k of them) or still on stack at the return (at most H).

Total

O(H + k)

Each push and pop is O(1).

Variable Definitions

nnn

Number of nodes in the tree

HHH

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

kkk

The rank asked for, 1 <= k <= n

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(1): one integer

Boundary Best / Worst Cases

Best Case

O(H)O(H)O(H): k = 1, one dive down the left edge and a single visit

Average Case

O(log⁡n+k)O(\log n + k)O(logn+k) on a balanced tree

Worst Case

O(n)O(n)O(n): k = n, or a chain of height nnn

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: "binary search tree", "the k-th smallest value". A rank question on a BST: BST Inorder, read as a stream that stops after k visits.

CONSTRAINTS & BOUNDS

n≤104n \le 10^4n≤104 nodes, 1≤k≤n1 \le k \le n1≤k≤n. Copying every value into a list and sorting costs O(nlog⁡n)O(n \log n)O(nlogn) time and O(n)O(n)O(n) memory; the iterative walk stops after k visits, so it costs O(H+k)O(H + k)O(H+k) time and only the O(H)O(H)O(H) stack, where HHH is the tree height (log⁡n\log nlogn when balanced, up to nnn on a chain).

FAANG PRODUCTION TRAPS & EDGE CASES

A chain of 10410^4104 nodes is 10410^4104 levels deep: a recursive walk can overflow a small call stack, and the explicit stack avoids that. LeetCode's follow-up (many queries while nodes are inserted and deleted) calls for storing each node's subtree size, so one query walks a single root-to-leaf path in O(H)O(H)O(H).

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