LeetCode Python/Java/C++/JS > Stack and Queue > 13. Roman to Integer > Solved in Ruby, Python, Java > GitHub or Repost
LeetCode link: 13. Roman to Integer, difficulty: Easy.
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
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.
Example 1:
Input: s = "III"
Output: 3
Example 2:
Input: s = "IV"
Output: 4
Example 3:
Input: s = "IX"
Output: 9
Example 4:
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 5:
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90, 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]
.
Hint 1
Problem is simpler to solve by working the string from back to front and using a map.
Intuition
- The correspondence between characters and values can be represented with a
Map
. - The intuition is to add the value to
result
whenever a digit is encountered. - But cases like
IV
may occur, so you need to consider whether to process from left to right or from right to left. Which processing direction do you choose?Click to view the answer
Processing from right to left is more convenient, because once you see that the current character and the previous character form a specific combination, you can handle it directly.
- How do you deal with cases like
IV
?Click to view the answer
Just handle it in reverse. In the forward direction you do addition, but now you do subtraction.
Complexity
Time complexity
O(N)
Space complexity
O(1)
Ruby #
# @param {String} s
# @return {Integer}
def roman_to_int(s)
symbol_to_value = {
'I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000,
}
result = 0
previous_char = nil
(s.size - 1).downto(0).each do |i|
char = s[i]
if ('I' == char && ['V', 'X'].include?(previous_char)) ||
('X' == char && ['L', 'C'].include?(previous_char)) ||
('C' == char && ['D', 'M'].include?(previous_char))
result -= symbol_to_value[char]
else
result += symbol_to_value[char]
end
previous_char = char
end
result
end
Python #
class Solution:
def romanToInt(self, s: str) -> int:
symbol_to_value = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000,
}
result = 0
previous_char = None
for i in range(len(s) - 1, -1, -1):
char = s[i]
if ('I' == char and previous_char in ['V', 'X']) or \
('X' == char and previous_char in ['L', 'C']) or \
('C' == char and previous_char in ['D', 'M']):
result -= symbol_to_value[char]
else:
result += symbol_to_value[char]
previous_char = char
return result
Java #
class Solution {
public int romanToInt(String s) {
Map<Character, Integer> symbolToValue = new HashMap<>();
symbolToValue.put('I', 1);
symbolToValue.put('V', 5);
symbolToValue.put('X', 10);
symbolToValue.put('L', 50);
symbolToValue.put('C', 100);
symbolToValue.put('D', 500);
symbolToValue.put('M', 1000);
var result = 0;
Character previousChar = null;
for (var i = s.length() - 1; i >= 0; i--) {
var currentChar = s.charAt(i);
if (previousChar != null && (
(currentChar == 'I' && (previousChar == 'V' || previousChar == 'X')) ||
(currentChar == 'X' && (previousChar == 'L' || previousChar == 'C')) ||
(currentChar == 'C' && (previousChar == 'D' || previousChar == 'M')))) {
result -= symbolToValue.get(currentChar);
} else {
result += symbolToValue.get(currentChar);
}
previousChar = currentChar;
}
return result;
}
}