Back to blog
Sep 08, 2025
16 min read

Roman to Integer

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given a roman numeral, convert it to an integer.

Difficulty: Easy | Acceptance: 65.34% | Paid: No

Topics: Hash Table, Math, String

Examples

Example 1

Input:

s = "III"

Output:

3

Explanation: III = 3.

Example 2

Input:

s = "LVIII"

Output:

58

Explanation: L = 50, V= 5, III = 3.

Example 3

Input:

s = "MCMXCIV"

Output:

1994

Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

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].

Brute Force Approach

Intuition

We can sum up all values directly and then correct for subtraction cases. First pass to add all normal values, then second pass to subtract 2x the smaller value for each special case (because we counted it once too many in the first pass).

Steps

  • Iterate through the string and add the value of each character based on a lookup table.
  • Then iterate again to check for the special subtraction cases and adjust the total accordingly.
  • For each subtraction case, we must subtract twice the value of the smaller character (since it was already added once).
python
def romanToInt(s: str) -> int:
    roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    total = 0
    
    # First pass: Add all values
    for char in s:
        total += roman_map[char]
    
    # Second pass: Adjust for subtraction cases
    for i in range(len(s) - 1):
        if s[i] == 'I' and (s[i+1] == 'V' or s[i+1] == 'X'):
            total -= 2
        elif s[i] == 'X' and (s[i+1] == 'L' or s[i+1] == 'C'):
            total -= 20
        elif s[i] == 'C' and (s[i+1] == 'D' or s[i+1] == 'M'):
            total -= 200
            
    return total

Complexity

  • Time: O(n) where n is the length of the string, as we iterate through the string twice
  • Space: O(1) as we only use a fixed-size map and a few variables

Optimal One-Pass Approach

Intuition

Instead of two passes, we can process the string left to right in a single pass. When we encounter a character that is smaller than the next character, we subtract its value; otherwise, we add it. This directly handles the subtraction cases.

Steps

  • Iterate through the string from left to right.
  • At each step, compare the current character’s value with the next character’s value.
  • If the current value is less than the next value, subtract the current value from the total (this handles cases like IV, IX, etc.).
  • Otherwise, add the current value to the total.
  • Handle the last character separately since there’s no next character to compare with.
python
def romanToInt(s: str) -> int:
    roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    total = 0
    
    for i in range(len(s)):
        if i &lt; len(s) - 1 and roman_map[s[i]] &lt; roman_map[s[i+1]]:
            total -= roman_map[s[i]]
        else:
            total += roman_map[s[i]]
            
    return total

Complexity

  • Time: O(n) where n is the length of the string, as we iterate through the string once
  • Space: O(1) as we only use a fixed-size map and a few variables

Reverse Iteration Approach

Intuition

We can iterate from right to left. When we see a character that is smaller than the previous character (the one we just processed), we subtract its value. This is another way to naturally handle subtraction cases.

Steps

  • Start from the rightmost character and move left.
  • Keep track of the value of the previously processed character.
  • If the current character’s value is less than the previous one, subtract it from the total.
  • Otherwise, add it to the total.
  • Update the previous character’s value after each iteration.
python
def romanToInt(s: str) -> int:
    roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    total = 0
    prev_value = 0
    
    for i in range(len(s) - 1, -1, -1):
        current_value = roman_map[s[i]]
        if current_value &lt; prev_value:
            total -= current_value
        else:
            total += current_value
        prev_value = current_value
            
    return total

Complexity

  • Time: O(n) where n is the length of the string, as we iterate through the string once
  • Space: O(1) as we only use a fixed-size map and a few variables