LeetCode "13. Roman to Integer"
(Source/Credits: https://dev.to/takakd/leetcode-13-roman-to-integer-5f05)
Solution of LeetCode "13. Roman to Integer"
title: LeetCode "13. Roman to Integer" published: true description: Solution of LeetCode "13. Roman to Integer" tags: [leetcode, python]
Umm...
How to remove a lot ofpos += 1
and pos < len_str
```python class Solution: def romanToInt(self, s: str) -> int:
if not s:
return 0
pos = 0
len_str = len(s)
numOfDigits = 0
symbols = ['dummy', ('I', 'V', 'X'), ('X', 'L', 'C'), ('C', 'D', 'M'), ('M')]
s = s[::-1]
value = 0
while pos < len_str:
num = 0
numOfDigits += 1
# ex. I ... III, VI ... VIII
if s[pos] == symbols[numOfDigits][0]:
num = 1
pos += 1
while pos < len_str and s[pos] == symbols[numOfDigits][0]:
num += 1
pos += 1
if pos < len_str and s[pos] == symbols[numOfDigits][1]:
num += 5
pos += 1
# ex. V, IV
elif s[pos] == symbols[numOfDigits][1]:
num = 5
pos += 1
if pos < len_str and s[pos] == symbols[numOfDigits][0]:
num -= 1
pos += 1
# ex. IX, XC, M
elif s[pos] == symbols[numOfDigits][2]:
num = 10
pos += 1
if pos < len_str and s[pos] == symbols[numOfDigits][0]:
num -= 1
pos += 1
value += num * (10 ** (numOfDigits - 1))
return value
```
Comments section
orenovadia
•May 1, 2024
Besides
pos += 1
appearing multiple times in the code, I think there is a bigger problem withs[pos] == symbols[numOfDigits][X]
: it makes it difficult to understand what number each roman character is mapped to. Since each roman character is mapped to a decimal number, it makes sense putting them in adict
like so:``` ROMAN_TO_DECIMAL = {'I': 1, 'V': 5 ...}
```
This makes things easy. Let's assume for a moment that we have a roman number without reverse-order subtractions (e.g: without
IV
,IX
).Than you could simply write:
``` number = 0 for roman in s: number += ROMAN_TO_DECIMAL[roman] return number
```
This is very neat. And can even be written in one line:
sum(ROMAN_TO_DECIMAL[c] for c in s)
How to add the reverse-order subtractions now? Consider and try to implement this pseudo-code:
``` for roman in s: value = ROMAN_TO_DECIMAL[roman] if the next roman character is larger than the current: # e.g: this character is the 'I' in 'IV', so it should be subtracted from the result number -= value else: number += value
```
takakd Author
•May 1, 2024
Wow! Thank you for the detailed explanation and code example!😍
I implemented:
``` ROMAN_TO_DECIMAL = {'I': 1, 'V':5, 'X':10, 'L':50, 'C':100, 'D': 500, 'M':1000}
len_s = len(s) number = 0 for i in range(len_s - 1): value = ROMAN_TO_DECIMAL[s[i]] if ROMAN_TO_DECIMAL[s[i]] < ROMAN_TO_DECIMAL[s[i + 1]]: number -= value else: number += value
last
number += ROMAN_TO_DECIMAL[s[len_s - 1]] return number
```
I could not come up with the idea of
ROMAN_TO_DECIMAL
.😭When thinking about this problem, did you first think about
ROMAN_TO_DECIMAL
and then the logic?Or is the logic first?
If it's ok with you, could you tell me about your thought process?