Roman to Integer
01 Apr 2020 | 3 minutes to readThe problem can be found in here.
Problem Description
Roman numerals are represented by seven different symbols:
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, two is written as II
in Roman numeral, just two one’s added together. Similarly, twelve is writtern as, XII
, which is simply X
+ 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
, which translated to V
minus I
. There are six instances where subtraction is used:
I
can be placed beforeV
(5) andX
(10) to make 4 and 9X
can be placed beforeL
(50) andC
(100) to make 40 and 90C
can be placed beforeD
(500) andM
(1000) to make 400 and 900
Problem
Given a string of Roman numeral, convert it to an integer.
Assume:
- Input is guaranteed to be within the range from 1 to 3999
Example
Input: "III"
Output: 3
Input: "LVIII"
Output: 58
Input: "MCMXCIV"
Output: 1994
Algorithm
Assuming that we are given a Roman numeral that is written from the largest to smallest, we can loop through each characters of the given Roman numeral string and add them together. To get the character’s corresponding integer value, a pre-defined hashmap can be used (ie. symbol_map
).
However, there is one small modification required due to our special rule for subtraction. Since we are accepting a valid input all the time and the only case that this rule applies is when the previous character is “smaller” than the current character.
Let’s take XIV
to see what modification is required.
Loop 1:
previous = None
current = "X"
result = 0 + 10 = 10
Loop 2:
previous = "X"
current = "I"
result = 10 + 1 = 11
Loop 3:
previous = "I"
current = "V"
previous < current
result = 11 - 1 = 10 # undo the previous loop
result = 10 + 5 - 1 = 14 # perform the subtraction
result = 14
Generally the subtraction step is described as the following:
result = result - previous + current - previous
= result - 2 * previous + current
Code
def romanToInt(s):
result = 0
symbol_map = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000
}
previous = ""
for c in s:
if previous:
if symbol_map[previous] < symbol_map[c]:
result -= 2 * symbol_map[previous]
result += symbol_map[c]
previous = c
return result
Analysis
Let’s say the length of the givin input string is n
.
The time complexity of this algorithm is O(n)
as we traverse the string just once.
The space complexity here is O(1)
as we only have a static mapping for the space.