LC 13. Roman to Integer
- Published on
- Reading time
- 2 min read
The problem
First Solution
In this quick and dirty first attempt, I just wrote out all the cases. It's a little long but gets the job done:
function romanToInt(s: string): number {
let answer: number = 0
for (let i = 0; i < s.length; i++) {
if (s[i] === 'I') {
if (s[i + 1] === 'V') {
answer += 4
i++
} else if (s[i + 1] === 'X') {
answer += 9
i++
} else {
answer++
}
} else if (s[i] === 'V') {
answer += 5
} else if (s[i] === 'X') {
if (s[i + 1] === 'L') {
answer += 40
i++
} else if (s[i + 1] === 'C') {
answer += 90
i++
} else {
answer += 10
}
} else if (s[i] === 'L') {
answer += 50
} else if (s[i] === 'C') {
if (s[i + 1] === 'D') {
answer += 400
i++
} else if (s[i + 1] === 'M') {
answer += 900
i++
} else {
answer += 100
}
} else if (s[i] === 'D') {
answer += 500
} else if (s[i] === 'M') {
answer += 1000
}
}
return answer
}
More concise solution
I find this solution less readable as it has a trick to it. Here, all numbers are added, but 2 * previous
is subtracted when an edge case is identified. For example, 'IV'
would add 1
first, then add 5 - 1 - 1
to give 4. Again, 1
is subtracted first to give the value 4
and subtracted a second time to offset the previous iterations increment:
function romanToInt(s: string): number {
const valueMap = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
}
let answer: number = 0
for (let i = 0; i < s.length; i++) {
if (valueMap[s[i]] > valueMap[s[i - 1]]) {
// Subtract double the previous value since it was added
// incorrectly in the previous iteration
answer += valueMap[s[i]] - 2 * valueMap[s[i - 1]]
} else {
answer += valueMap[s[i]]
}
}
return answer
}