A step-by-step walkthrough of the Roman to Integer LeetCode problem in JavaScript. Two solutions covered: a readable approach with full comments and an optimized one-liner version.
Recently I worked through the Roman to Integer problem on LeetCode. It’s a solid exercise for practicing object lookups and loop logic in JavaScript, and the subtraction rule makes it more interesting than it first appears. Here’s how I approached it, with two solutions.
The Problem
Given a string representing a Roman numeral, convert it to an integer.
Roman numerals use seven symbols:
Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000
Numerals are written from largest to smallest, left to right. So 2 is II, 3 is III. But there are six subtraction cases where a smaller symbol placed before a larger one means you subtract rather than add:
IbeforeV(5) orX(10) gives 4 and 9XbeforeL(50) orC(100) gives 40 and 90CbeforeD(500) orM(1000) gives 400 and 900
For example, MCMXCIV = 1000 + (1000 – 100) + (100 – 10) + (5 – 1) = 1994.
Solution 1: Step-by-Step (Readable Version)
Step 1. Create a lookup object mapping each Roman symbol to its integer value.
const symbols = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
};
Step 2. Initialize a result variable.
let result = 0;
Step 3. Loop through each character in the string.
for (let i = 0; i < s.length; i++) {
}
Step 4. Inside the loop, get the value of the current symbol and the next one.
const current = symbols[s[i]];
const next = symbols[s[i + 1]];
On the first iteration with "MCMXCIV":
current = symbols["M"] => 1000 next = symbols["C"] => 100
Step 5. If the current value is less than the next, this is a subtraction pair (like IV). Add the difference and skip the next character by incrementing i. Otherwise, just add the current value.
if (current < next) {
result += next - current; // IV -> 5 - 1 = 4
i++;
} else {
result += current;
}
Step 6. Return the result.
return result;
Full solution:
let romanToInt = (s) => {
const symbols = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
};
let result = 0;
for (let i = 0; i < s.length; i++) {
const current = symbols[s[i]];
const next = symbols[s[i + 1]];
if (current < next) {
result += next - current;
i++;
} else {
result += current;
}
}
return result;
};
Solution 2: Optimized (Ternary Version)
The same logic in a more compact form. Instead of the if/else block, a ternary operator handles both cases in one line. If the current symbol’s value is less than the next, subtract it from the total. Otherwise add it.
var romanToInt = function(s) {
const symbols = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
};
let result = 0;
for (let i = 0; i < s.length; i++) {
symbols[s[i]] < symbols[s[i + 1]]
? result -= symbols[s[i]]
: result += symbols[s[i]];
}
return result;
};
This version doesn’t skip characters explicitly — instead it relies on subtraction directly. When I appears before V, the loop subtracts 1 on the first pass, then adds 5 on the next, which gives the same result of 4. Slightly less explicit, but cleaner to read once you’re familiar with the pattern.

