Convert a Roman Numeral to an Integer

Solve this Problem
Medium15–20 min
Topics
Companies
Practice:GFG ↗
Given a Roman numeral string s, convert it to its integer value. Roman numerals are normally written largest-to-smallest left to right — but six specific pairs (IV, IX, XL, XC, CD, CM) flip that: a smaller symbol placed just before a larger one means subtract instead of add. Looking up each symbol's value with a chain of if/else comparisons works, but it's the kind of lookup a hash mapHash MapA data structure that maps keys to values with O(1) average lookup time, instead of scanning through a list or chain of comparisons. was built for: build the 7 symbol-to-value pairs once, and every subsequent lookup becomes a single O(1) step. The core trick — comparing each symbol's value against the one right after it — stays the same either way: if the current symbol is smaller than the next one, it's part of a subtractive pair.

Test Case 1:

Input:s = "MCMXCIV"
Output:1994
Explanation:Contains three subtractive pairs: CM=900, XC=90, IV=4, plus M=1000 → 1000+900+90+4=1994.

Test Case 2:

Input:s = "III"
Output:3
Explanation:No subtractive pairs — just three I's added together.

Test Case 3:

Input:s = "LVIII"
Output:58
Explanation:L=50, V=5, III=3, no subtractive pairs — straightforward addition.

Constraints

  • 1 ≤ s.length ≤ 15
  • s is a valid Roman numeral in the range [1, 3999]
  • Symbols used: I(1), V(5), X(10), L(50), C(100), D(500), M(1000)
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

🧪Try your own test case
1class Solution {
2 public int romanToInt(String s) {
3 Map<Character, Integer> values = new HashMap<>();
4 values.put('I', 1); values.put('V', 5); values.put('X', 10);
5 values.put('L', 50); values.put('C', 100); values.put('D', 500); values.put('M', 1000);
6 int total = 0;
7 for (int i = 0; i < s.length(); i++) {
8 int current = values.get(s.charAt(i));
9 if (i + 1 < s.length() && current < values.get(s.charAt(i + 1))) {
10 total -= current;
11 } else {
12 total += current;
13 }
14 }
15 return total;
16 }
17}
18
M
C
M
X
C
I
V
Variables
total0
INITIALIZE

Build a hash map of all 7 symbol values once (I=1, V=5, X=10, L=50, C=100, D=500, M=1000). Start total at 0.

Step 1 / 16

Approach & Solutions

Brute Force — If/Else Chain Lookup

Brute

For each character, find its value with a chain of if/else comparisons (no map) — then look up the next character's value the same way, and compare the two to decide whether to add or subtract. Still O(n) overall, but every lookup repeats the same chain of comparisons instead of a single O(1) step, and adding a new symbol later means editing the chain in two places.

TimeO(n)
SpaceO(1)
1class Solution { 2 public int romanToInt(String s) { 3 int total = 0; 4 for (int i = 0; i < s.length(); i++) { 5 int current = valueOf(s.charAt(i)); 6 int next = (i + 1 < s.length()) ? valueOf(s.charAt(i + 1)) : 0; 7 if (current < next) { 8 total -= current; 9 } else { 10 total += current; 11 } 12 } 13 return total; 14 } 15 16 private int valueOf(char c) { 17 if (c == 'I') return 1; 18 if (c == 'V') return 5; 19 if (c == 'X') return 10; 20 if (c == 'L') return 50; 21 if (c == 'C') return 100; 22 if (c == 'D') return 500; 23 if (c == 'M') return 1000; 24 return 0; 25 } 26}

Optimal — Hash Map Lookup

Optimal

Build a hash map of all 7 symbol values once, up front. Then walk the string a single time — each lookup is now O(1) instead of a repeated chain of comparisons, and the code stays clean and easy to extend. Same time complexity as the brute force, but simpler and faster in practice.

TimeO(n)
SpaceO(1)
1class Solution { 2 public int romanToInt(String s) { 3 Map<Character, Integer> values = new HashMap<>(); 4 values.put('I', 1); values.put('V', 5); values.put('X', 10); 5 values.put('L', 50); values.put('C', 100); values.put('D', 500); values.put('M', 1000); 6 int total = 0; 7 for (int i = 0; i < s.length(); i++) { 8 int current = values.get(s.charAt(i)); 9 if (i + 1 < s.length() && current < values.get(s.charAt(i + 1))) { 10 total -= current; 11 } else { 12 total += current; 13 } 14 } 15 return total; 16 } 17}

Related Problems