LeetCode: Roman to Integer

Convert a Roman numeral to an integer.

Posted on LeetCode Python

See original problem on leetcode.com

Difficulty: Easy

First Approach

My first approach was to iterate through the string, checking both the current character and previous character. The “trick” is that sometimes we are adding 800 to the return value, since we’ve already added 100 for the “C” and now need to add 900 for “CM”.

Runtime

7 ms | Beats 42.17%

class Solution:
def romanToInt(self, s: str) -> int:
value = 0
prev_char = None
for idx in range(len(s)):
char = s[idx]
if char == "M" and prev_char == "C":
value += 800
elif char == "D" and prev_char == "C":
value += 300
elif char == "C" and prev_char == "X":
value += 80
elif char == "L" and prev_char == "X":
value += 30
elif char == "X" and prev_char == "I":
value += 8
elif char == "V" and prev_char == "I":
value += 3
elif char == "M":
value += 1000
elif char == "D":
value += 500
elif char == "C":
value += 100
elif char == "L":
value += 50
elif char == "X":
value += 10
elif char == "V":
value += 5
elif char == "I":
value += 1
prev_char = char
return value

Second Approach

For my second attempt, I created a mapping of both single and double character Roman numerals to their integer values. I then iterated through the string, checking for two-character matches first, and falling back to single-character matches.

This improved the time from 7 ms to 3 ms.

Runtime

3 ms | Beats 79.99%

class Solution:
def romanToInt(self, s: str) -> int:
char_map = {
"CM": 900,
"CD": 400,
"XC": 90,
"XL": 40,
"IX": 9,
"IV": 4,
"M": 1000,
"D": 500,
"C": 100,
"L": 50,
"X": 10,
"V": 5,
"I": 1,
}
result = 0
idx = 0
while idx < len(s):
# Check for two characters
if idx < len(s) - 1 and s[idx:idx + 2] in char_map:
result += char_map[s[idx:idx + 2]]
idx += 2
continue
# Otherwise, one character
result += char_map[s[idx]]
idx += 1
return result