Sweaty Imposter

Roman to Integer

EasyArrays & HashingNeetCode 150JuniorOpen on LeetCodeUpdated

You're given a valid Roman numeral s. Return its integer value. The symbols are I = 1, V = 5, X = 10, L = 50, C = 100, D = 500 and M = 1000. Symbols are normally written from largest to smallest and added, as in XII = 12. When a smaller symbol comes right before a larger one it is subtracted instead, which gives the six pairs IV = 4, IX = 9, XL = 40, XC = 90, CD = 400 and CM = 900.

Examples

s = "III" returns 3

Three I's, each worth 1, add up to 3.

s = "LVIII" returns 58

L = 50, V = 5 and III = 3. Each symbol is at least as large as the one after it, so every value is added.

s = "MCMXCIV" returns 1994

M = 1000, CM = 900, XC = 90 and IV = 4. In each pair the smaller symbol comes first, so it is subtracted from the one after it.

Constraints

  • 1 <= s.length <= 15
  • s contains only the characters I, V, X, L, C, D, M.
  • It's guaranteed that s is a valid Roman numeral in the range [1, 3999].

Hints

Hint 1

Most symbols just add their value. When exactly does a symbol count as negative instead?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Look up each symbol's value in a small table. A symbol is subtracted exactly when it is smaller than the symbol right after it (the I in IV, the C in CM), and added otherwise. So walk the string once, compare each value with the next one (0 past the end), and add or subtract. This covers all six subtractive pairs without listing them.

Time

O(n)

Space

O(1)

Pitfall

The last symbol has no next symbol, so reading s[i + 1] there goes out of bounds; treat it as 0 so the final symbol is always added. Subtract only when the very next symbol is larger: in MCM the C is subtracted, but the first M is added.

Solutions

class Solution {
    public int romanToInt(String s) {
        Map<Character, Integer> val = Map.of(
            'I', 1, 'V', 5, 'X', 10, 'L', 50,
            'C', 100, 'D', 500, 'M', 1000
        );
        int total = 0;
        for (int i = 0; i < s.length(); i++) {
            int cur = val.get(s.charAt(i));
            int next = i + 1 < s.length() ? val.get(s.charAt(i + 1)) : 0;
            if (cur < next) total -= cur;
            else total += cur;
        }
        return total;
    }
}
Drill This