LeetCode: Roman to Integer
Convert a Roman numeral to an integer.
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 valueSecond 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