Roman to Integer
You're given a valid Roman numeral s. Return its integer value. The symbols are I = 1, V = 5, X = 10, L = 50, C = 100, D = 500 and M = 1000. Symbols are normally written from largest to smallest and added, as in XII = 12. When a smaller symbol comes right before a larger one it is subtracted instead, which gives the six pairs IV = 4, IX = 9, XL = 40, XC = 90, CD = 400 and CM = 900.
Examples
s = "III" returns 3
Three I's, each worth 1, add up to 3.
s = "LVIII" returns 58
L = 50, V = 5 and III = 3. Each symbol is at least as large as the one after it, so every value is added.
s = "MCMXCIV" returns 1994
M = 1000, CM = 900, XC = 90 and IV = 4. In each pair the smaller symbol comes first, so it is subtracted from the one after it.
Constraints
- 1 <= s.length <= 15
- s contains only the characters I, V, X, L, C, D, M.
- It's guaranteed that s is a valid Roman numeral in the range [1, 3999].
Hints
Most symbols just add their value. When exactly does a symbol count as negative instead?
Use a hash map from symbol to value, and compare each symbol with the one right after it.
For each index i, look up cur and the next value (0 at the end). If cur < next, subtract cur from the total; otherwise add it. Return the total.
Drill This: Your Approach First
Approach
Look up each symbol's value in a small table. A symbol is subtracted exactly when it is smaller than the symbol right after it (the I in IV, the C in CM), and added otherwise. So walk the string once, compare each value with the next one (0 past the end), and add or subtract. This covers all six subtractive pairs without listing them.
Time
O(n)
Space
O(1)
Pitfall
Solutions
class Solution {
public int romanToInt(String s) {
Map<Character, Integer> val = Map.of(
'I', 1, 'V', 5, 'X', 10, 'L', 50,
'C', 100, 'D', 500, 'M', 1000
);
int total = 0;
for (int i = 0; i < s.length(); i++) {
int cur = val.get(s.charAt(i));
int next = i + 1 < s.length() ? val.get(s.charAt(i + 1)) : 0;
if (cur < next) total -= cur;
else total += cur;
}
return total;
}
}class Solution:
def romanToInt(self, s: str) -> int:
val = {'I': 1, 'V': 5, 'X': 10, 'L': 50,
'C': 100, 'D': 500, 'M': 1000}
total = 0
for i, ch in enumerate(s):
cur = val[ch]
nxt = val[s[i + 1]] if i + 1 < len(s) else 0
total += -cur if cur < nxt else cur
return total