Roman numerals into integersRoman to Integer in JavaScript: Two Solutions Explained (LeetCode Problem #13)

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:

  • I before V (5) or X (10) gives 4 and 9
  • X before L (50) or C (100) gives 40 and 90
  • C before D (500) or M (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 &lt; 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 &lt; s.length; i++) {
    const current = symbols[s[i]];
    const next = symbols[s[i + 1]];

    if (current &lt; 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.


Related Posts