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•Dynamic Programming
HardLC 10

Regular Expression Matching (LeetCode 10)

Target Frequency:GoogleMetaAmazon

You're given a text string s and a regex-style pattern p built from ordinary characters plus two special ones: '.', which stands for any single character, and '*', which repeats the element right before it zero or more times.

Determine whether p matches s in full, start to end -- a partial match doesn't count.

Worked Examples

Example 1
Input:s = "aa", p = "a"
Output:false
Explanation: "a" does not match the entire string "aa".
Example 2
Input:s = "aa", p = "a*"
Output:true
Explanation: Here '*' lets the 'a' before it repeat any number of times, so repeating it once turns the pattern into effectively "aa", which matches.
Example 3
Input:s = "ab", p = ".*"
Output:true
Explanation: "." means "zero or more () of any character (.)".

⚖️Formal Constraints & Bounds

  • 1 <= s.length <= 20

  • 1 <= p.length <= 20

  • s contains only lowercase English letters.

  • p contains only lowercase English letters, '.', and '*'.

  • It is guaranteed for each appearance of the character '*', there will be a previous valid character to match.

Deep-Dive & Conceptual Insights

Core Insight

Regex's '' always modifies the SINGLE element immediately before it (never the raw '' symbol alone), so its transition must look 2 positions back in the pattern to skip the whole 'element*' pair (dp[i][j-2]) or 1 position back in the string to repeat that same element (dp[i-1][j]).

Real-World Scenario & Production Applications

Regex engines behind log-parsing, input validation, and search tools; compiler lexer token matching.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: '*' Zeroes Out Its Paired Element

Define dp[i][j] as True iff s[:i] fully matches p[:j]. Because '*' always modifies the single element immediately before it, the base row must skip by 2 when it sees '*': an all-'element*' pattern like "a*b*c*" can still match the empty string.

Mathematical Recurrence / Code Invariant
dp = [[False] * (N + 1) for _ in range(M + 1)]
dp[0][0] = True
for j in range(1, N + 1):
    if p[j - 1] == '*':
        dp[0][j] = dp[0][j - 2]  # skip the whole element* pair

Step-by-Step Execution Trace Table

s prefixp prefixRule Applieddp Cell Value
""""Base caseTrue
"""a*"'*' zeroes out preceding 'a' (dp[0][j-2])True
"a""a*"'*' repeats 'a' once (dp[i-1][j])True
"aa""a*"Final cell: full matchTrue
Code Shape
Archetype Code Shape
Python
1dp = [[False]*(n+1) for _ in range(m+1)]
2dp[0][0] = True
3for j in range(1, n + 1):
4 if p[j-1] == '*':
5 dp[0][j] = dp[0][j-2]
6for i in range(1, m + 1):
7 for j in range(1, n + 1):
8 if p[j-1] in ('.', s[i-1]):
9 dp[i][j] = dp[i-1][j-1]
10 elif p[j-1] == '*':
11 dp[i][j] = dp[i][j-2]
12 if p[j-2] in ('.', s[i-1]):
13 dp[i][j] = dp[i][j] or dp[i-1][j]
14 else:
15 dp[i][j] = False
16return dp[m][n]

Conceptual Narrative

The hardest problem in Dual Sequence & String DP: Regular Expression Matching's '' operator (zero-or-more of the PRECEDING element, not the raw literal '') makes this one of the hardest "easy-sounding" DP problems in the entire canon.

🧭 Conceptual Foundation & Pattern Intuition

The critical trap that separates this from Wildcard Matching: in regex, '*' never appears alone -- it always modifies the single character immediately before it. So 'a*' means "zero or more 'a' characters," and '.*' means "zero or more of ANY character." This means every time the DP loop sees p[j-1] == '*', it must look back one MORE position to p[j-2] to find out what element is being repeated. Getting this indexing wrong is the single most common bug in every "hard" regex DP write-up.

👑 The Analogy: A Rubber-Stamp Duplicator, Not a Blank Wildcard

Wildcard's '*' is a rubber band that can stretch over ANY characters. Regex's '*' is a rubber-stamp duplicator bolted to exactly one preceding character (or the '.' wildcard character) -- it can only print that SAME element zero, one, or many times in a row. So dp[i][j] for a '*' cell must consider two completely different hypotheses: (1) the 'element*' pair contributed nothing to the match (treat it as if it weren't there at all: dp[i][j-2]), or (2) the element the '*' is stamping actually matches the current source character s[i-1], so one more copy can be "peeled off" while keeping the SAME 'element*' pair available for peeling again (dp[i-1][j]).

🔑 The Key Idea in the Code

Notice dp[i][j] = dp[i][j-2] looks BACKWARD in the pattern by 2 (skipping the whole element* pair), while the repeat case dp[i-1][j] looks backward in the STRING by 1 but stays at the SAME pattern column j -- because the same '*' might need to consume several more source characters in a row.

  • Independent asterisk evaluation: Treating * as an independent token. In regex, * always modifies the preceding character. You must inspect p[j-1] == '*' and evaluate the preceding character p[j-2].

  • Zero-occurrence branch omission: Forgetting the zero-occurrence transition for x*. dp[i][j] must always inherit dp[i][j-2] (completely discarding the character and asterisk pair).

  • Preceding dot match condition: When evaluating the 1-or-more match branch for .*, forgetting to verify that either p[j-2] == s[i-1] OR p[j-2] == '.' before allowing dp[i][j] = dp[i-1][j].

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Boolean full-string match against a pattern where '*' modifies the single preceding element (not itself a raw wildcard), plus '.' for any single character.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: dp[i][j] is True iff s[:i] can be fully matched by p[:j], where '*' is always paired with the character immediately before it in p.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Treating '*' like Wildcard Matching's free-standing wildcard instead of a suffix on the preceding element -- must look back to p[j-2], not just p[j-1].

  • Forgetting the base row must skip by 2 (dp[0][j] = dp[0][j-2]) to respect the element* pairing, not skip by 1 like Wildcard Matching's base row.

  • Missing the OR: dp[i][j] = dp[i][j-2] (zero occurrences) must be combined with dp[i-1][j] (one more occurrence) only when p[j-2] actually matches s[i-1].

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I build an (m+1) x (n+1) boolean grid with dp[0][0] = True. The base row only advances by 2: dp[0][j] = dp[0][j-2] when p[j-1] == '*'. For each cell, '.' or a literal match inherits dp[i-1][j-1]. For '*', I first assume zero occurrences of the paired element: dp[i][j] = dp[i][j-2]; then, if that element (p[j-2]) matches s[i-1] or is '.', I OR in dp[i-1][j] to allow one more repetition. Runs in O(M · N) time and O(M · N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(M · N)

Look at the execution steps: 2D boolean DP table for string s of length M and pattern p of length N. Each cell does O(1) work: diagonal inheritance for '.'/literal, or a 2-way OR that looks back 2 pattern columns for '*'.

SPACE COMPLEXITY

O(M · N) Auxiliary

Look at memory allocations: Call stack uses O(1) Iterative. Full (M+1) x (N+1) boolean grid retained (can be rolled to O(N) with two 1D rows).

Formal Recurrence Relation

T(M, N) = M · N = O(M · N)

Derivation Progression

'.' / Literal Transition

dp[i][j] = dp[i-1][j-1]

O(1) diagonal inheritance when characters match or pattern char is '.'.

'*' Pair Branch

dp[i][j] = dp[i][j-2] or (match(p[j-2], s[i-1]) and dp[i-1][j])

O(1) OR of 'skip the whole element* pair' and 'repeat the paired element one more time'.

Full Grid Fill

O(M · N) total cells

Every cell computed exactly once in row-major order.

Variable Definitions

MMM

Length of the input string s

NNN

Length of the pattern p

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(M · N) boolean grid (or O(N) with rolling rows)

🟢 Output Space

O(1) boolean result

Boundary Best / Worst Cases

Best Case

O(M⋅N)O(M · N)O(M⋅N)

Average Case

O(M⋅N)O(M · N)O(M⋅N)

Worst Case

O(M⋅N)O(M · N)O(M⋅N)

State-Space & Subproblem DAG(Directed Acyclic Graph) Topology

State-Space & Subproblem DAG(Directed Acyclic Graph) Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "'.' matches any char", "'*' matches zero or more of preceding element". Lookback token alignment: unlike LC 44, the star in regex binds strictly to the PRECEDING token p[j−2]p[j-2]p[j−2].

CONSTRAINTS & BOUNDS

s,p≤20s, p \le 20s,p≤20. Small dimensions allow full 2D table or memoized recursion.

Theory Context•Dynamic Programming
HardLC 10

Regular Expression Matching (LeetCode 10)

Target Frequency:GoogleMetaAmazon

You're given a text string s and a regex-style pattern p built from ordinary characters plus two special ones: '.', which stands for any single character, and '*', which repeats the element right before it zero or more times.

Determine whether p matches s in full, start to end -- a partial match doesn't count.

Worked Examples

Example 1
Input:s = "aa", p = "a"
Output:false
Explanation: "a" does not match the entire string "aa".
Example 2
Input:s = "aa", p = "a*"
Output:true
Explanation: Here '*' lets the 'a' before it repeat any number of times, so repeating it once turns the pattern into effectively "aa", which matches.
Example 3
Input:s = "ab", p = ".*"
Output:true
Explanation: "." means "zero or more () of any character (.)".

⚖️Formal Constraints & Bounds

  • 1 <= s.length <= 20

  • 1 <= p.length <= 20

  • s contains only lowercase English letters.

  • p contains only lowercase English letters, '.', and '*'.

  • It is guaranteed for each appearance of the character '*', there will be a previous valid character to match.

Deep-Dive & Conceptual Insights

Core Insight

Regex's '' always modifies the SINGLE element immediately before it (never the raw '' symbol alone), so its transition must look 2 positions back in the pattern to skip the whole 'element*' pair (dp[i][j-2]) or 1 position back in the string to repeat that same element (dp[i-1][j]).

Real-World Scenario & Production Applications

Regex engines behind log-parsing, input validation, and search tools; compiler lexer token matching.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: '*' Zeroes Out Its Paired Element

Define dp[i][j] as True iff s[:i] fully matches p[:j]. Because '*' always modifies the single element immediately before it, the base row must skip by 2 when it sees '*': an all-'element*' pattern like "a*b*c*" can still match the empty string.

Mathematical Recurrence / Code Invariant
dp = [[False] * (N + 1) for _ in range(M + 1)]
dp[0][0] = True
for j in range(1, N + 1):
    if p[j - 1] == '*':
        dp[0][j] = dp[0][j - 2]  # skip the whole element* pair

Step-by-Step Execution Trace Table

s prefixp prefixRule Applieddp Cell Value
""""Base caseTrue
"""a*"'*' zeroes out preceding 'a' (dp[0][j-2])True
"a""a*"'*' repeats 'a' once (dp[i-1][j])True
"aa""a*"Final cell: full matchTrue
Code Shape
Archetype Code Shape
Python
1dp = [[False]*(n+1) for _ in range(m+1)]
2dp[0][0] = True
3for j in range(1, n + 1):
4 if p[j-1] == '*':
5 dp[0][j] = dp[0][j-2]
6for i in range(1, m + 1):
7 for j in range(1, n + 1):
8 if p[j-1] in ('.', s[i-1]):
9 dp[i][j] = dp[i-1][j-1]
10 elif p[j-1] == '*':
11 dp[i][j] = dp[i][j-2]
12 if p[j-2] in ('.', s[i-1]):
13 dp[i][j] = dp[i][j] or dp[i-1][j]
14 else:
15 dp[i][j] = False
16return dp[m][n]

Conceptual Narrative

The hardest problem in Dual Sequence & String DP: Regular Expression Matching's '' operator (zero-or-more of the PRECEDING element, not the raw literal '') makes this one of the hardest "easy-sounding" DP problems in the entire canon.

🧭 Conceptual Foundation & Pattern Intuition

The critical trap that separates this from Wildcard Matching: in regex, '*' never appears alone -- it always modifies the single character immediately before it. So 'a*' means "zero or more 'a' characters," and '.*' means "zero or more of ANY character." This means every time the DP loop sees p[j-1] == '*', it must look back one MORE position to p[j-2] to find out what element is being repeated. Getting this indexing wrong is the single most common bug in every "hard" regex DP write-up.

👑 The Analogy: A Rubber-Stamp Duplicator, Not a Blank Wildcard

Wildcard's '*' is a rubber band that can stretch over ANY characters. Regex's '*' is a rubber-stamp duplicator bolted to exactly one preceding character (or the '.' wildcard character) -- it can only print that SAME element zero, one, or many times in a row. So dp[i][j] for a '*' cell must consider two completely different hypotheses: (1) the 'element*' pair contributed nothing to the match (treat it as if it weren't there at all: dp[i][j-2]), or (2) the element the '*' is stamping actually matches the current source character s[i-1], so one more copy can be "peeled off" while keeping the SAME 'element*' pair available for peeling again (dp[i-1][j]).

🔑 The Key Idea in the Code

Notice dp[i][j] = dp[i][j-2] looks BACKWARD in the pattern by 2 (skipping the whole element* pair), while the repeat case dp[i-1][j] looks backward in the STRING by 1 but stays at the SAME pattern column j -- because the same '*' might need to consume several more source characters in a row.

  • Independent asterisk evaluation: Treating * as an independent token. In regex, * always modifies the preceding character. You must inspect p[j-1] == '*' and evaluate the preceding character p[j-2].

  • Zero-occurrence branch omission: Forgetting the zero-occurrence transition for x*. dp[i][j] must always inherit dp[i][j-2] (completely discarding the character and asterisk pair).

  • Preceding dot match condition: When evaluating the 1-or-more match branch for .*, forgetting to verify that either p[j-2] == s[i-1] OR p[j-2] == '.' before allowing dp[i][j] = dp[i-1][j].

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Boolean full-string match against a pattern where '*' modifies the single preceding element (not itself a raw wildcard), plus '.' for any single character.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: dp[i][j] is True iff s[:i] can be fully matched by p[:j], where '*' is always paired with the character immediately before it in p.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Treating '*' like Wildcard Matching's free-standing wildcard instead of a suffix on the preceding element -- must look back to p[j-2], not just p[j-1].

  • Forgetting the base row must skip by 2 (dp[0][j] = dp[0][j-2]) to respect the element* pairing, not skip by 1 like Wildcard Matching's base row.

  • Missing the OR: dp[i][j] = dp[i][j-2] (zero occurrences) must be combined with dp[i-1][j] (one more occurrence) only when p[j-2] actually matches s[i-1].

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I build an (m+1) x (n+1) boolean grid with dp[0][0] = True. The base row only advances by 2: dp[0][j] = dp[0][j-2] when p[j-1] == '*'. For each cell, '.' or a literal match inherits dp[i-1][j-1]. For '*', I first assume zero occurrences of the paired element: dp[i][j] = dp[i][j-2]; then, if that element (p[j-2]) matches s[i-1] or is '.', I OR in dp[i-1][j] to allow one more repetition. Runs in O(M · N) time and O(M · N) space."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(M · N)

Look at the execution steps: 2D boolean DP table for string s of length M and pattern p of length N. Each cell does O(1) work: diagonal inheritance for '.'/literal, or a 2-way OR that looks back 2 pattern columns for '*'.

SPACE COMPLEXITY

O(M · N) Auxiliary

Look at memory allocations: Call stack uses O(1) Iterative. Full (M+1) x (N+1) boolean grid retained (can be rolled to O(N) with two 1D rows).

Formal Recurrence Relation

T(M, N) = M · N = O(M · N)

Derivation Progression

'.' / Literal Transition

dp[i][j] = dp[i-1][j-1]

O(1) diagonal inheritance when characters match or pattern char is '.'.

'*' Pair Branch

dp[i][j] = dp[i][j-2] or (match(p[j-2], s[i-1]) and dp[i-1][j])

O(1) OR of 'skip the whole element* pair' and 'repeat the paired element one more time'.

Full Grid Fill

O(M · N) total cells

Every cell computed exactly once in row-major order.

Variable Definitions

MMM

Length of the input string s

NNN

Length of the pattern p

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(M · N) boolean grid (or O(N) with rolling rows)

🟢 Output Space

O(1) boolean result

Boundary Best / Worst Cases

Best Case

O(M⋅N)O(M · N)O(M⋅N)

Average Case

O(M⋅N)O(M · N)O(M⋅N)

Worst Case

O(M⋅N)O(M · N)O(M⋅N)

State-Space & Subproblem DAG(Directed Acyclic Graph) Topology

State-Space & Subproblem DAG(Directed Acyclic Graph) Topology
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "'.' matches any char", "'*' matches zero or more of preceding element". Lookback token alignment: unlike LC 44, the star in regex binds strictly to the PRECEDING token p[j−2]p[j-2]p[j−2].

CONSTRAINTS & BOUNDS

s,p≤20s, p \le 20s,p≤20. Small dimensions allow full 2D table or memoized recursion.

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