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•Math & Geometry
MediumLC 12

Integer to Roman (LeetCode 12)

Target Frequency:GoogleMetaAmazon

Roman numerals rest on seven letters, each pinned to a fixed value:

SymbolValue
I1
V5
X10
L50
C100
D500
M1000

Build the numeral one decimal place at a time (thousands, then hundreds, then tens, then ones), stacking each place's encoding onto the result. Two encoding rules govern each place:

  • Normal case: keep peeling off the largest symbol value that still fits, appending it and shrinking the remainder, until nothing is left for that place.
  • Subtractive shortcut: whenever a place's digit is 4 or 9, write it as one smaller symbol placed directly before the next larger one instead of repeating a symbol awkwardly -- so 4 becomes IV (one before five) and 9 becomes IX (one before ten). The full set of shortcuts is 4 -> IV, 9 -> IX, 40 -> XL, 90 -> XC, 400 -> CD, 900 -> CM.
  • Only the "power of ten" symbols (I, X, C, M) may ever repeat, and never more than three times back to back; V, L, and D never repeat -- a fourth copy always means switching to the subtractive shortcut instead.

Your job: take an integer and produce its Roman numeral string.

Worked Examples

Example 1
Input:num = 3749
Output:"MMMDCCXLIX"
Explanation: 3000 = MMM, 700 = DCC, 40 = XL, 9 = IX
Example 2
Input:num = 58
Output:"LVIII"
Explanation: 50 = L, 8 = VIII
Example 3
Input:num = 1994
Output:"MCMXCIV"
Explanation: 1000 = M, 900 = CM, 90 = XC, 4 = IV

⚖️Formal Constraints & Bounds

  • 1 <= num <= 3999

Deep-Dive & Conceptual Insights

Core Insight

Encode every subtractive rule (4, 9, 40, 90, 400, 900) directly as first-class entries in an ordered value/symbol table, so the runtime logic becomes a single uniform greedy loop with zero per-digit special-casing.

Real-World Scenario & Production Applications

Legacy document/edition numbering systems, clock-face and monument inscriptions, and any format that still requires canonical Roman numeral rendering.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Ordered Value/Symbol Lookup Table

Build a strictly decreasing table of (value, symbol) pairs that already encodes every subtractive-notation rule (900=CM, 400=CD, 90=XC, 40=XL, 9=IX, 4=IV) as first-class entries, not special cases.

Mathematical Recurrence / Code Invariant
values  = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]

Step-by-Step Execution Trace Table

Denomination ValueRoman SymbolTimes Divisible (num // v)Subtracted Value (qty * v)Remaining numAppended Roman String
1000M1994 // 1000 = 11000994"M"
900CM994 // 900 = 190094"MCM"
90XC94 // 90 = 1904"MCMXC"
4IV4 // 4 = 140"MCMXCIV"
Code Shape
Archetype Code Shape
Python
1values, symbols = [1000, 900, ...], ["M", "CM", ...]
2for v, s in zip(values, symbols):
3 count = num // v
4 if count:
5 res.append(s * count)
6 num -= v * count
7return "".join(res)

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Converting a number to Roman numerals looks like it needs special-case logic for every awkward subtractive pattern (4, 9, 40, 90, 400, 900) — but a single greedy walk over a carefully ordered lookup table handles every case uniformly.

The Analogy: Making Change With a Cash Drawer

Imagine a cash drawer stocked with specially minted "bills" of value 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, and 1 (the 900/400/90/40/9/4 "bills" are the subtractive-notation trick in disguise). To make change for any amount, a cashier doesn't think about special cases — they just always hand over the biggest bill that still fits, again and again, until the drawer amount reaches zero. Because the bill values already encode the subtractive rules (a "900" bill just is CM), the greedy hand-over produces valid Roman numeral notation automatically.

🔑 The Key Idea in the Code

Because values is strictly decreasing and includes the subtractive pairs (900, 400, 90, 40, 9, 4) as first-class entries, the greedy num // v step never needs to special-case "is this a 4-like or 9-like digit?" — the table already answers that question.

  • Missing subtractive combination pairs in lookup table: Roman numerals use subtractive notation for 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD), and 900 (CM). Omitting these 6 entries forces complex conditional branching.

  • Descending order requirement: The lookup table must be iterated strictly in descending order of value (1000 down to 1). Ascending iteration greedily chooses 'I' for everything.

  • Building strings via repeated concatenation: In languages without string builders, repeated string concatenation in loops causes O(L2)O(L^2)O(L2) copying; collect symbol tokens in a list and call ''.join().

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Convert an integer (1 to 3999) into a Roman numeral string, including subtractive forms (4, 9, 40, 90, 400, 900).

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: encoding the subtractive pairs (900=CM, 400=CD, 90=XC, 40=XL, 9=IX, 4=IV) as first-class table entries removes any need for per-digit special-casing.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Hand-writing separate branches for each subtractive case instead of putting them directly in the ordered table.

  • Forgetting the table must be strictly decreasing by value or the greedy walk breaks.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I build a strictly decreasing table of (value, symbol) pairs that already bakes in the subtractive forms as entries. I walk the table top to bottom; at each entry I take as many copies as fit (num // v), append that many symbols, and subtract their total value from num. The loop stops once num reaches 0. This runs in O(1) time since the table has a fixed 13 entries."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(1)

Look at the loop bound: the value/symbol table has a fixed 13 entries regardless of input size, and num <= 3999 means the loop body executes at most a small constant number of times across all entries. Strict O(1) time.

SPACE COMPLEXITY

O(1) Auxiliary

Look at memory allocations: the values and symbols tables are fixed-size constants (13 entries each). The output string is bounded by a constant maximum length (15 characters for num = 3888). O(1) auxiliary space.

Formal Recurrence Relation

T(N) = O(1) since the table has a fixed 13 entries

Derivation Progression

Table Walk

13 table entries, constant work per entry

Every entry does O(1) division and string append work.

Total Runtime

O(1) bounded by fixed table size

Runtime never depends on the magnitude of num beyond its fixed 4-digit constraint.

Variable Definitions

numnumnum

Input integer, 1 <= num <= 3999

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(1) Fixed-size lookup tables

🟢 Output Space

O(1) Bounded-length output string

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1)

Average Case

O(1)O(1)O(1)

Worst Case

O(1)O(1)O(1)

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Keyword trigger: "convert an integer to a Roman numeral". The structural requirement is mapping numbers to additive and subtractive Roman literals. A Senior SWE avoids complex conditional branching trees by framing this as a Greedy Value/Symbol Table Walk.

CONSTRAINTS & BOUNDS

1≤num≤39991 \le num \le 39991≤num≤3999. Domain size is strictly finite. Time and space complexities are strictly O(1)O(1)O(1).

FAANG PRODUCTION TRAPS & EDGE CASES

There are exactly 13 unique symbol pairs in total.

Theory Context•Math & Geometry
MediumLC 12

Integer to Roman (LeetCode 12)

Target Frequency:GoogleMetaAmazon

Roman numerals rest on seven letters, each pinned to a fixed value:

SymbolValue
I1
V5
X10
L50
C100
D500
M1000

Build the numeral one decimal place at a time (thousands, then hundreds, then tens, then ones), stacking each place's encoding onto the result. Two encoding rules govern each place:

  • Normal case: keep peeling off the largest symbol value that still fits, appending it and shrinking the remainder, until nothing is left for that place.
  • Subtractive shortcut: whenever a place's digit is 4 or 9, write it as one smaller symbol placed directly before the next larger one instead of repeating a symbol awkwardly -- so 4 becomes IV (one before five) and 9 becomes IX (one before ten). The full set of shortcuts is 4 -> IV, 9 -> IX, 40 -> XL, 90 -> XC, 400 -> CD, 900 -> CM.
  • Only the "power of ten" symbols (I, X, C, M) may ever repeat, and never more than three times back to back; V, L, and D never repeat -- a fourth copy always means switching to the subtractive shortcut instead.

Your job: take an integer and produce its Roman numeral string.

Worked Examples

Example 1
Input:num = 3749
Output:"MMMDCCXLIX"
Explanation: 3000 = MMM, 700 = DCC, 40 = XL, 9 = IX
Example 2
Input:num = 58
Output:"LVIII"
Explanation: 50 = L, 8 = VIII
Example 3
Input:num = 1994
Output:"MCMXCIV"
Explanation: 1000 = M, 900 = CM, 90 = XC, 4 = IV

⚖️Formal Constraints & Bounds

  • 1 <= num <= 3999

Deep-Dive & Conceptual Insights

Core Insight

Encode every subtractive rule (4, 9, 40, 90, 400, 900) directly as first-class entries in an ordered value/symbol table, so the runtime logic becomes a single uniform greedy loop with zero per-digit special-casing.

Real-World Scenario & Production Applications

Legacy document/edition numbering systems, clock-face and monument inscriptions, and any format that still requires canonical Roman numeral rendering.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Ordered Value/Symbol Lookup Table

Build a strictly decreasing table of (value, symbol) pairs that already encodes every subtractive-notation rule (900=CM, 400=CD, 90=XC, 40=XL, 9=IX, 4=IV) as first-class entries, not special cases.

Mathematical Recurrence / Code Invariant
values  = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]

Step-by-Step Execution Trace Table

Denomination ValueRoman SymbolTimes Divisible (num // v)Subtracted Value (qty * v)Remaining numAppended Roman String
1000M1994 // 1000 = 11000994"M"
900CM994 // 900 = 190094"MCM"
90XC94 // 90 = 1904"MCMXC"
4IV4 // 4 = 140"MCMXCIV"
Code Shape
Archetype Code Shape
Python
1values, symbols = [1000, 900, ...], ["M", "CM", ...]
2for v, s in zip(values, symbols):
3 count = num // v
4 if count:
5 res.append(s * count)
6 num -= v * count
7return "".join(res)

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Converting a number to Roman numerals looks like it needs special-case logic for every awkward subtractive pattern (4, 9, 40, 90, 400, 900) — but a single greedy walk over a carefully ordered lookup table handles every case uniformly.

The Analogy: Making Change With a Cash Drawer

Imagine a cash drawer stocked with specially minted "bills" of value 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, and 1 (the 900/400/90/40/9/4 "bills" are the subtractive-notation trick in disguise). To make change for any amount, a cashier doesn't think about special cases — they just always hand over the biggest bill that still fits, again and again, until the drawer amount reaches zero. Because the bill values already encode the subtractive rules (a "900" bill just is CM), the greedy hand-over produces valid Roman numeral notation automatically.

🔑 The Key Idea in the Code

Because values is strictly decreasing and includes the subtractive pairs (900, 400, 90, 40, 9, 4) as first-class entries, the greedy num // v step never needs to special-case "is this a 4-like or 9-like digit?" — the table already answers that question.

  • Missing subtractive combination pairs in lookup table: Roman numerals use subtractive notation for 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD), and 900 (CM). Omitting these 6 entries forces complex conditional branching.

  • Descending order requirement: The lookup table must be iterated strictly in descending order of value (1000 down to 1). Ascending iteration greedily chooses 'I' for everything.

  • Building strings via repeated concatenation: In languages without string builders, repeated string concatenation in loops causes O(L2)O(L^2)O(L2) copying; collect symbol tokens in a list and call ''.join().

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Convert an integer (1 to 3999) into a Roman numeral string, including subtractive forms (4, 9, 40, 90, 400, 900).

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: encoding the subtractive pairs (900=CM, 400=CD, 90=XC, 40=XL, 9=IX, 4=IV) as first-class table entries removes any need for per-digit special-casing.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Hand-writing separate branches for each subtractive case instead of putting them directly in the ordered table.

  • Forgetting the table must be strictly decreasing by value or the greedy walk breaks.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I build a strictly decreasing table of (value, symbol) pairs that already bakes in the subtractive forms as entries. I walk the table top to bottom; at each entry I take as many copies as fit (num // v), append that many symbols, and subtract their total value from num. The loop stops once num reaches 0. This runs in O(1) time since the table has a fixed 13 entries."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(1)

Look at the loop bound: the value/symbol table has a fixed 13 entries regardless of input size, and num <= 3999 means the loop body executes at most a small constant number of times across all entries. Strict O(1) time.

SPACE COMPLEXITY

O(1) Auxiliary

Look at memory allocations: the values and symbols tables are fixed-size constants (13 entries each). The output string is bounded by a constant maximum length (15 characters for num = 3888). O(1) auxiliary space.

Formal Recurrence Relation

T(N) = O(1) since the table has a fixed 13 entries

Derivation Progression

Table Walk

13 table entries, constant work per entry

Every entry does O(1) division and string append work.

Total Runtime

O(1) bounded by fixed table size

Runtime never depends on the magnitude of num beyond its fixed 4-digit constraint.

Variable Definitions

numnumnum

Input integer, 1 <= num <= 3999

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(1) Fixed-size lookup tables

🟢 Output Space

O(1) Bounded-length output string

Boundary Best / Worst Cases

Best Case

O(1)O(1)O(1)

Average Case

O(1)O(1)O(1)

Worst Case

O(1)O(1)O(1)

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Keyword trigger: "convert an integer to a Roman numeral". The structural requirement is mapping numbers to additive and subtractive Roman literals. A Senior SWE avoids complex conditional branching trees by framing this as a Greedy Value/Symbol Table Walk.

CONSTRAINTS & BOUNDS

1≤num≤39991 \le num \le 39991≤num≤3999. Domain size is strictly finite. Time and space complexities are strictly O(1)O(1)O(1).

FAANG PRODUCTION TRAPS & EDGE CASES

There are exactly 13 unique symbol pairs in total.

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