CMD Guide
HomeDSAArrays

easy Roman to Integer

Problem Statement

Given the Roman numeral string s, convert it into its equivalent integer and return it.

Roman numerals use combinations of seven symbols: I, V, X, L, C, D, and M, representing values 1, 5, 10, 50, 100, 500, and 1000 respectively.

For example, I is equivalent to 1, II is equivalent to 2, and XI is equivalent to 11 (X + I). In some cases, a smaller numeral before a larger numeral indicates subtraction (e.g., IV = 4).

Examples

Example 1:

Example 2:

Example 3:

Constraints:

Try it yourself

Try solving this question here:

After you try — Pattern Transfer

Pattern: ONE-PASS LOOKUP + LOOKAHEAD (subtractive rule on sequential tokens).

Recognition signals: sequence of tokens with values; smaller-before-larger means subtract; otherwise add. String treated as a char array.

Template: map each symbol to a value; for each index i, if i+1 exists and v[i] < v[i+1] then subtract v[i], else add v[i].

When NOT: if you must validate illegal roman forms → grammar / allowed-pair state machine (only IV, IX, XL, XC, CD, CM). This problem guarantees a valid numeral in [1, 3999].

Worked micro-example: IV → I<V so −1, then +5 → 4.

Edges to implement carefully

🎯 STRICT STANDOUT: Why / complexity derivation / pattern+when-not / edges / drills — Roman to Integer easy

Why this exists (judgment layer)

Token stream with a local subtractive rule teaches one-pass lookahead without full parsing. Interviewers use it to probe map design and edge handling on the last symbol.

Worked example & complexity derivation

Map: I1 V5 X10 L50 C100 D500 M1000
Rule: if v[i] < v[i+1] then total −= v[i] else total += v[i]; last always +
XLII: X<L → −10; L → +50; I → +1; I → +1 = 42
CXCIV: C<X? no +100; X<C → −10; C +100; I<V → −1; V +5 = 194
Time: one pass O(n) with n≤15; space O(1) map of 7 symbols

Pattern transfer & when-NOT

Pattern: ONE-PASS LOOKUP + LOOKAHEAD on sequential tokens. When-NOT: validate illegal forms (IIII, IC) — need allowed-pair grammar / state machine. This problem guarantees valid [1,3999]. Not two-pointers; not sliding window.

Edge cases (hand-run)

"I" → 1 (no lookahead). "IV" → 4. "III" → 3. "MCMXCIV" → 1994. Last character always added. Empty not in constraints (length ≥1).

Hostile-panel drills (defend the decision)

Q1. Trace MCMXCIV to 1994.
Model answer: M+1000; C<M → −100; M+1000; X<C → −10; C+100; I<V → −1; V+5 = 1994.

Q2. Why not always add then special-case pairs?
Model answer: Lookahead unifies subtractive pairs (IV,IX,XL,XC,CD,CM) in one rule without branching per pair name.

Q3. Complexity if n were 10⁶ valid roman-like tokens?
Model answer: Still O(n) time O(1) space — map is fixed size; no nested scans required.

✅ Solution Roman to Integer

Problem Statement

Given the Roman numeral string s, convert it into its equivalent integer and return it.

Roman numerals use combinations of seven symbols: I, V, X, L, C, D, and M, representing values 1, 5, 10, 50, 100, 500, and 1000 respectively.

For example, I is equivalent to 1, II is equivalent to 2, and XI is equivalent to 11 (X + I). In some cases, a smaller numeral before a larger numeral indicates subtraction (e.g., IV = 4).

Examples

Example 1:

  • Input: s = "XLII"
  • Output: 42
  • Justification: L (50) - X (10) + I (1) + I (1) = 42

Example 2:

  • Input: s = "CXCIV"
  • Output: 194
  • Justification: C (100) - X (10) + C (100) - I (1) + V (5) = 194

Example 3:

  • Input: s = "MMMCDXLIV"
  • Output: 3444
  • Justification: M (1000) + M (1000) + M (1000) - C (100) + D (500) - X (10) + L (50) - I (1) + V (5) = 3444

Constraints:

  • 1 <= s.length <= 15
  • s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
  • It is guaranteed that s is a valid roman numeral in the range [1, 3999].

Solution

To solve this problem, we will iterate through the Roman numeral string from left to right. We will use a dictionary to map Roman symbols to their integer values. If the current symbol represents a value smaller than the next symbol, it means we need to subtract this value. Otherwise, we add the current value to the total sum. This approach ensures we correctly handle both addition and subtraction cases in Roman numerals.

This approach works because it simplifies the problem into a series of comparisons and additions or subtractions. By checking each symbol against the next, we ensure that the unique rules of Roman numeral subtraction are adhered to without needing complex logic or nested conditions.

Step-by-Step Algorithm

  • Create a dictionary to map Roman numerals to their integer values.
  • Initialize a variable total to store the final integer value.
  • Iterate through the string:
    • If the current symbol's value is less than the next symbol's value, subtract the current symbol's value from total.
    • Otherwise, add the current symbol's value to total.
  • Return the total as the converted integer value.

Algorithm Walkthrough

Input: s = "MMMCDXLIV"

  1. Initialize result to 0.

  2. Create a dictionary of Roman numerals to integers:

    • {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
  3. Iterate through the string "MMMCDXLIV":

    • Iteration 1:

      • Current character: 'M'
      • Value: 1000
      • Next character: 'M'
      • Since 1000 >= 1000, add 1000 to result.
      • result = 0 + 1000 = 1000
    • Iteration 2:

      • Current character: 'M'
      • Value: 1000
      • Next character: 'M'
      • Since 1000 >= 1000, add 1000 to result.
      • result = 1000 + 1000 = 2000
    • Iteration 3:

      • Current character: 'M'
      • Value: 1000
      • Next character: 'C'
      • Since 1000 >= 100, add 1000 to result.
      • result = 2000 + 1000 = 3000
    • Iteration 4:

      • Current character: 'C'
      • Value: 100
      • Next character: 'D'
      • Since 100 < 500, subtract 100 from result.
      • result = 3000 - 100 = 2900
    • Iteration 5:

      • Current character: 'D'
      • Value: 500
      • Next character: 'X'
      • Since 500 >= 10, add 500 to result.
      • result = 2900 + 500 = 3400
    • Iteration 6:

      • Current character: 'X'
      • Value: 10
      • Next character: 'L'
      • Since 10 < 50, subtract 10 from result.
      • result = 3400 - 10 = 3390
    • Iteration 7:

      • Current character: 'L'
      • Value: 50
      • Next character: 'I'
      • Since 50 >= 1, add 50 to result.
      • result = 3390 + 50 = 3440
    • Iteration 8:

      • Current character: 'I'
      • Value: 1
      • Next character: 'V'
      • Since 1 < 5, subtract 1 from result.
      • result = 3440 - 1 = 3439
    • Iteration 9:

      • Current character: 'V'
      • Value: 5
      • No next character
      • Add 5 to result.
      • result = 3439 + 5 = 3444
  4. Final result is 3444.

Image
Image

Code

java
import java.util.HashMap;
import java.util.Map;

public class Solution {

  public int romanToInt(String s) {
    // Map of Roman numerals to integers
    Map<Character, Integer> romanMap = new HashMap<>();
    romanMap.put('I', 1);
    romanMap.put('V', 5);
    romanMap.put('X', 10);
    romanMap.put('L', 50);
    romanMap.put('C', 100);
    romanMap.put('D', 500);
    romanMap.put('M', 1000);

    int result = 0; // To store the final result
    int n = s.length();

    // Iterate through the string
    for (int i = 0; i < n; i++) {
      // Get the value of the current Roman numeral
      int value = romanMap.get(s.charAt(i));

      // Check if the current numeral is smaller than the next one
      if (i < n - 1 && value < romanMap.get(s.charAt(i + 1))) {
        result -= value; // Subtract the value
      } else {
        result += value; // Add the value
      }
    }
    return result; // Return the final result
  }

  public static void main(String[] args) {
    Solution solution = new Solution();
    System.out.println(solution.romanToInt("XLII")); // 42
    System.out.println(solution.romanToInt("CXCIV")); // 194
    System.out.println(solution.romanToInt("MMMCDXLIV")); // 3444
  }
}

Complexity Analysis

  • Time Complexity: , where n is the length of the input string. We iterate through the string once, performing constant-time operations for each character.
  • Space Complexity: , since the size of the dictionary is fixed and does not grow with the input size.

Pattern Transfer — SINGLE PASS WITH LOOKAHEAD (subtractive rule)

Pattern name: one-pass map + lookahead compare.

Recognition signals: sequential tokens; smaller-before-larger means combine-as-subtract; fixed small alphabet → O(1) map.

Template (left-to-right):

map = {I:1,V:5,X:10,L:50,C:100,D:500,M:1000}
total = 0
for i in 0..n-1:
  if i < n-1 and map[s[i]] < map[s[i+1]]: total -= map[s[i]]
  else: total += map[s[i]]
return total

Alternate (right-to-left): always add current; if previous (rightward) value is smaller than current, you already… simpler form: walk right-to-left, always add; if value < last_seen then subtract instead; update last_seen. Both are Θ(n).

When NOT: invalid-input detection needs explicit legal-pair checks (only IV, IX, XL, XC, CD, CM) and max-three-in-a-row rules — a pure lookahead adder accepts garbage.

Complexity: Θ(n) time (one visit per char). Space O(1) — map has 7 fixed entries, not growing with n.

Edge suite (hand-run)

  • "X": one iteration, no next → +10 → 10. Emphasize i < n-1 guard (classic off-by-one).
  • "IV": −1 + 5 = 4.
  • "III": +1+1+1 = 3.
  • "MMMCDXLIV": M+M+M −C +D −X +L −I +V = 3000−100+500−10+50−1+5 = 3444.

Drill: Rewrite with right-to-left and verify "IX" → 9.

🧩 Pattern · Arrays

Recognize it: Scan once tracking what you need (running max/sum), or precompute a prefix-sum / hash → turn O(n²) into O(n).

▶ Visualize this problem (step it, predict each fork)
⛶ Open this problem debugger in explore mode
🤖 Don't fully get this? Learn it with Claude

Stuck on Roman to Integer? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Roman to Integer** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Roman to Integer** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Roman to Integer**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Roman to Integer**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes