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•Advanced Data Structures
HardLC 212

Word Search II (LeetCode 212)

Target Frequency:GoogleAmazonMicrosoft

Given a character grid board and a list of words, find every word in words that can be spelled out by tracing a path through the board.

A path moves between horizontally or vertically adjacent cells one step at a time, and the same cell can't be reused twice within a single word.

Worked Examples

Example 1
Input:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
Output:["eat","oath"]
oaanetaeihkriflv
Explanation: oath and eat can be traced through neighbouring cells; pea and rain cannot.
Example 2
Input:board = [["a","b"],["c","d"]], words = ["abcb"]
Output:[]
abcd
Explanation: Spelling abcb would need the b cell twice, which is not allowed.

⚖️Formal Constraints & Bounds

  • m == board.length

  • n == board[i].length

  • 1 <= m, n <= 12

  • board[i][j] is a lowercase English letter.

  • 1 <= words.length <= 3 * 104

  • 1 <= words[i].length <= 10

  • words[i] consists of lowercase English letters.

  • All the strings of words are unique.

Deep-Dive & Conceptual Insights

Core Insight

A prefix tree converts brute-force repeated grid searches into a single branch-pruned traversal.

Real-World Scenario & Production Applications

Boggle game solvers, high-speed bioinformatic DNA motif search in genetic sequencing arrays.

Step-by-Step Execution Trace Table

Board CellVisited PathMatching Trie PrefixFound Word
(0, 0) 'o'['o']'o'-
(0, 1) 'a'['o', 'a']'oa'-
(1, 1) 't'['o', 'a', 't']'oat'-
(2, 1) 'h'['o', 'a', 't', 'h']'oath''oath'
Code Shape
Archetype Code Shape
Python
1Build dictionary Trie with terminal word markers
2def dfs(r, c, parent_node):
3 visit the cell and record a word that ends at this trie node
4 call dfs on each of the 4 neighbors whose letter is a child of this trie node
5for r, c in grid:
6 if board[r][c] in trie:
7 dfs(r, c, root)

Conceptual Narrative

Searching an M x N board for K words by running K separate DFS passes causes catastrophic TLE. Word Search II runs a single DFS guided by a Trie, pruning dead branches and unlinking matched words dynamically.

🧭 Conceptual Foundation & Pattern Intuition

Running naive DFS from every cell for each of the KKK words costs O(K⋅M⋅N⋅4L)O(K \cdot M \cdot N \cdot 4^L)O(K⋅M⋅N⋅4L), which is far too slow when K=3⋅104K = 3 \cdot 10^4K=3⋅104 and L=10L = 10L=10. The breakthrough is inverting the search: build a Trie from the word list, and let the board guide the Trie walk. From each grid cell (r,c)(r, c)(r,c), we explore adjacent cells only if the neighboring character matches a valid child in the active Trie node. If the Trie has no branch for that character, the DFS terminates immediately—pruning millions of futile paths before they start. To pass the strict LeetCode runtime constraints, two additional Senior SWE optimizations are mandatory:

  1. Word Deduplication: When a word is matched, clear curr.word = None so the same word found via a different path is never added twice.
  2. Dynamic Leaf Pruning: After visiting a child, if that child has zero remaining children (len(child.children) == 0), delete it from curr.children. This permanently prunes exhausted branches from the Trie, preventing future DFS walks from re-exploring dead subtrees.
🗺️ The Analogy: A Scouting Party With a Single Master Compass

Imagine sending an explorer into an ancient labyrinth to search for 1,000 lost artifacts. If the explorer searches for artifact #1, then returns to the entrance and searches for artifact #2, they walk the labyrinth 1,000 separate times. Instead, you hand them a single branched blueprint (the Trie) containing all 1,000 artifact paths simultaneously. At every junction, the explorer checks the blueprint: if none of the 1,000 paths go down the left hallway, that hallway is ignored immediately. When an artifact is found, they cross it off the blueprint; if an entire branch of the blueprint is crossed off, they remove that page so no future search ever looks in that wing again.

🔑 Why It Works

Dynamic leaf pruning collapses the Trie inward as words are discovered, converting worst-case exponential backtracking into an ultra-fast directed graph reduction.

  • Duplicate words from different grid paths: A word can be discovered via multiple distinct DFS paths on the board. When a terminal node is reached, append node.word and set node.word = None to prevent duplicate additions.

  • Trie leaf node pruning omission: Failing to prune leaf nodes after all matching words in a branch are found causes unnecessary DFS traversals into dead-end branches, triggering Time Limit Exceeded.

  • Un-marking visited board cell on backtrack: Mutating board[r][c] = '#' to mark visited must be reverted board[r][c] = char upon backtrack.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Finding multiple dictionary words inside a 2D character matrix.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: grid DFS only expands into cells whose character exists as a child in the current Trie node.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Running independent DFS for each word: O(K · M · N · 4^L) vs optimal O(M · N · 4^L).

  • Duplicate words collected: remove $ from Trie node upon match (curr.pop('$')).

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I insert all dictionary words into a Trie, storing complete words at terminal nodes. I iterate through each cell in the board and invoke DFS only if the cell character exists in the Trie root. In DFS, I mark visited cells with '#', recurse on matching neighbors, and restore the cell. Runs in O(M · N · 4^L) time and O(W · L) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(M · N · 4^L)

Look at the execution steps: Building Trie from W words takes O(W · L). From each of the M x N grid cells, DFS explores at most 4^L paths pruned by Trie prefix matching. Total O(M · N · 4^L).

SPACE COMPLEXITY

O(W · L) Auxiliary

Trie memory O(W · L) and recursion stack of max depth L.

Formal Recurrence Relation

T(M, N, L) = O(W · L) + (M · N) · 4^L

Derivation Progression

Trie Construction

O(W · L) prefix tree build

Indexes all dictionary words simultaneously.

Grid Cell Iteration

M · N starting positions

Initiates DFS only if character exists in root TrieNode.

Trie Pruned Exploration

4^L max steps per cell

Instantly prunes paths not matching any dictionary prefix in O(1).

Variable Definitions

MMM

Total number of rows in the grid

NNN

Total number of columns in the grid

LLL

Maximum length of any word in dictionary

WWW

Number of words in dictionary

Memory Architecture & Bounds

🟣 Call Stack

O(L) Recursion call stack (L = max word length)

🔵 Auxiliary Heap

O(W · L) Trie tree

🟢 Output Space

O(K · L) List of found words

Boundary Best / Worst Cases

Best Case

O(W⋅L+M⋅N)O(W · L + M · N)O(W⋅L+M⋅N) if no grid chars match word prefixes.

Average Case

O(M⋅N⋅4L)O(M · N · 4^L)O(M⋅N⋅4L).

Worst Case

O(M⋅N⋅4L)O(M · N · 4^L)O(M⋅N⋅4L) if all paths match valid prefixes.

Recurrence Tree Topology

Recurrence Tree Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "find all words on the board", "board of characters", "dictionary of words". Naive grid DFS for each dictionary word takes O(W×M⋅N⋅4L)O(W \times M \cdot N \cdot 4^L)O(W×M⋅N⋅4L), which is far too slow for 3×1043 \times 10^43×104 words. A Senior SWE inverts the search: Store Dictionary in a Trie + Single Pass Grid DFS with Prefix Pruning. If a character on the board does not match any branch in the Trie, the entire DFS subtree is pruned in O(1)O(1)O(1)!

CONSTRAINTS & BOUNDS

Board 12×1212 \times 1212×12, words ≤3×104\le 3 \times 10^4≤3×104, word length ≤10\le 10≤10. Time budget: O(M⋅N⋅4L)O(M \cdot N \cdot 4^L)O(M⋅N⋅4L) with aggressive Trie branch pruning, running in <200< 200<200ms.

FAANG PRODUCTION TRAPS & EDGE CASES

Duplicate words emitted: when a word can be constructed via multiple valid paths on the board, duplicate matches occur. A Senior SWE sets curr_node.word = None immediately after adding it to the result set. Trie Pruning Optimization: delete leaf nodes after finding a word (del parent.children[ch]) to prevent revisiting dead subtrees.

Theory Context•Advanced Data Structures
HardLC 212

Word Search II (LeetCode 212)

Target Frequency:GoogleAmazonMicrosoft

Given a character grid board and a list of words, find every word in words that can be spelled out by tracing a path through the board.

A path moves between horizontally or vertically adjacent cells one step at a time, and the same cell can't be reused twice within a single word.

Worked Examples

Example 1
Input:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
Output:["eat","oath"]
oaanetaeihkriflv
Explanation: oath and eat can be traced through neighbouring cells; pea and rain cannot.
Example 2
Input:board = [["a","b"],["c","d"]], words = ["abcb"]
Output:[]
abcd
Explanation: Spelling abcb would need the b cell twice, which is not allowed.

⚖️Formal Constraints & Bounds

  • m == board.length

  • n == board[i].length

  • 1 <= m, n <= 12

  • board[i][j] is a lowercase English letter.

  • 1 <= words.length <= 3 * 104

  • 1 <= words[i].length <= 10

  • words[i] consists of lowercase English letters.

  • All the strings of words are unique.

Deep-Dive & Conceptual Insights

Core Insight

A prefix tree converts brute-force repeated grid searches into a single branch-pruned traversal.

Real-World Scenario & Production Applications

Boggle game solvers, high-speed bioinformatic DNA motif search in genetic sequencing arrays.

Step-by-Step Execution Trace Table

Board CellVisited PathMatching Trie PrefixFound Word
(0, 0) 'o'['o']'o'-
(0, 1) 'a'['o', 'a']'oa'-
(1, 1) 't'['o', 'a', 't']'oat'-
(2, 1) 'h'['o', 'a', 't', 'h']'oath''oath'
Code Shape
Archetype Code Shape
Python
1Build dictionary Trie with terminal word markers
2def dfs(r, c, parent_node):
3 visit the cell and record a word that ends at this trie node
4 call dfs on each of the 4 neighbors whose letter is a child of this trie node
5for r, c in grid:
6 if board[r][c] in trie:
7 dfs(r, c, root)

Conceptual Narrative

Searching an M x N board for K words by running K separate DFS passes causes catastrophic TLE. Word Search II runs a single DFS guided by a Trie, pruning dead branches and unlinking matched words dynamically.

🧭 Conceptual Foundation & Pattern Intuition

Running naive DFS from every cell for each of the KKK words costs O(K⋅M⋅N⋅4L)O(K \cdot M \cdot N \cdot 4^L)O(K⋅M⋅N⋅4L), which is far too slow when K=3⋅104K = 3 \cdot 10^4K=3⋅104 and L=10L = 10L=10. The breakthrough is inverting the search: build a Trie from the word list, and let the board guide the Trie walk. From each grid cell (r,c)(r, c)(r,c), we explore adjacent cells only if the neighboring character matches a valid child in the active Trie node. If the Trie has no branch for that character, the DFS terminates immediately—pruning millions of futile paths before they start. To pass the strict LeetCode runtime constraints, two additional Senior SWE optimizations are mandatory:

  1. Word Deduplication: When a word is matched, clear curr.word = None so the same word found via a different path is never added twice.
  2. Dynamic Leaf Pruning: After visiting a child, if that child has zero remaining children (len(child.children) == 0), delete it from curr.children. This permanently prunes exhausted branches from the Trie, preventing future DFS walks from re-exploring dead subtrees.
🗺️ The Analogy: A Scouting Party With a Single Master Compass

Imagine sending an explorer into an ancient labyrinth to search for 1,000 lost artifacts. If the explorer searches for artifact #1, then returns to the entrance and searches for artifact #2, they walk the labyrinth 1,000 separate times. Instead, you hand them a single branched blueprint (the Trie) containing all 1,000 artifact paths simultaneously. At every junction, the explorer checks the blueprint: if none of the 1,000 paths go down the left hallway, that hallway is ignored immediately. When an artifact is found, they cross it off the blueprint; if an entire branch of the blueprint is crossed off, they remove that page so no future search ever looks in that wing again.

🔑 Why It Works

Dynamic leaf pruning collapses the Trie inward as words are discovered, converting worst-case exponential backtracking into an ultra-fast directed graph reduction.

  • Duplicate words from different grid paths: A word can be discovered via multiple distinct DFS paths on the board. When a terminal node is reached, append node.word and set node.word = None to prevent duplicate additions.

  • Trie leaf node pruning omission: Failing to prune leaf nodes after all matching words in a branch are found causes unnecessary DFS traversals into dead-end branches, triggering Time Limit Exceeded.

  • Un-marking visited board cell on backtrack: Mutating board[r][c] = '#' to mark visited must be reverted board[r][c] = char upon backtrack.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Finding multiple dictionary words inside a 2D character matrix.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: grid DFS only expands into cells whose character exists as a child in the current Trie node.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Running independent DFS for each word: O(K · M · N · 4^L) vs optimal O(M · N · 4^L).

  • Duplicate words collected: remove $ from Trie node upon match (curr.pop('$')).

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I insert all dictionary words into a Trie, storing complete words at terminal nodes. I iterate through each cell in the board and invoke DFS only if the cell character exists in the Trie root. In DFS, I mark visited cells with '#', recurse on matching neighbors, and restore the cell. Runs in O(M · N · 4^L) time and O(W · L) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(M · N · 4^L)

Look at the execution steps: Building Trie from W words takes O(W · L). From each of the M x N grid cells, DFS explores at most 4^L paths pruned by Trie prefix matching. Total O(M · N · 4^L).

SPACE COMPLEXITY

O(W · L) Auxiliary

Trie memory O(W · L) and recursion stack of max depth L.

Formal Recurrence Relation

T(M, N, L) = O(W · L) + (M · N) · 4^L

Derivation Progression

Trie Construction

O(W · L) prefix tree build

Indexes all dictionary words simultaneously.

Grid Cell Iteration

M · N starting positions

Initiates DFS only if character exists in root TrieNode.

Trie Pruned Exploration

4^L max steps per cell

Instantly prunes paths not matching any dictionary prefix in O(1).

Variable Definitions

MMM

Total number of rows in the grid

NNN

Total number of columns in the grid

LLL

Maximum length of any word in dictionary

WWW

Number of words in dictionary

Memory Architecture & Bounds

🟣 Call Stack

O(L) Recursion call stack (L = max word length)

🔵 Auxiliary Heap

O(W · L) Trie tree

🟢 Output Space

O(K · L) List of found words

Boundary Best / Worst Cases

Best Case

O(W⋅L+M⋅N)O(W · L + M · N)O(W⋅L+M⋅N) if no grid chars match word prefixes.

Average Case

O(M⋅N⋅4L)O(M · N · 4^L)O(M⋅N⋅4L).

Worst Case

O(M⋅N⋅4L)O(M · N · 4^L)O(M⋅N⋅4L) if all paths match valid prefixes.

Recurrence Tree Topology

Recurrence Tree Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "find all words on the board", "board of characters", "dictionary of words". Naive grid DFS for each dictionary word takes O(W×M⋅N⋅4L)O(W \times M \cdot N \cdot 4^L)O(W×M⋅N⋅4L), which is far too slow for 3×1043 \times 10^43×104 words. A Senior SWE inverts the search: Store Dictionary in a Trie + Single Pass Grid DFS with Prefix Pruning. If a character on the board does not match any branch in the Trie, the entire DFS subtree is pruned in O(1)O(1)O(1)!

CONSTRAINTS & BOUNDS

Board 12×1212 \times 1212×12, words ≤3×104\le 3 \times 10^4≤3×104, word length ≤10\le 10≤10. Time budget: O(M⋅N⋅4L)O(M \cdot N \cdot 4^L)O(M⋅N⋅4L) with aggressive Trie branch pruning, running in <200< 200<200ms.

FAANG PRODUCTION TRAPS & EDGE CASES

Duplicate words emitted: when a word can be constructed via multiple valid paths on the board, duplicate matches occur. A Senior SWE sets curr_node.word = None immediately after adding it to the result set. Trie Pruning Optimization: delete leaf nodes after finding a word (del parent.children[ch]) to prevent revisiting dead subtrees.

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