13. Roman to Integer*

​https://leetcode.com/problems/roman-to-integer/​

题目描述

Roman numerals are represented by seven different symbols: ​​I​​​, ​​V​​​, ​​X​​​, ​​L​​​, ​​C​​​, ​​D​​​ and ​​M​​.

Symbol       Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

For example, two is written as ​​II​​​ in Roman numeral, just two one’s added together. Twelve is written as, ​​XII​​​, which is simply ​​X + II​​​. The number twenty seven is written as ​​XXVII​​​, which is ​​XX + V + II​​.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not ​​IIII​​​. Instead, the number four is written as ​​IV​​​. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as ​​IX​​. There are six instances where subtraction is used:

  • ​I​​​ can be placed before​​V​​​ (5) and​​X​​ (10) to make 4 and 9.
  • ​X​​​ can be placed before​​L​​​ (50) and​​C​​ (100) to make 40 and 90.
  • ​C​​​ can be placed before​​D​​​ (500) and​​M​​ (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input: "III"
Output: 3

Example 2:

Input: "IV"
Output: 4

Example 3:

Input: "IX"
Output: 9

Example 4:

Input: "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 5:

Input: "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

题目描述

本题是 12. Integer to Roman**​ 的逆变换. 仍旧使用哈希表, 当访问到 ​​s[i]​​​ 时, 判断 ​​s[i, i+1]​​​ 这个子字符串是否在哈希表中 (比如 “IV”, “CM”). 如果不存在, 说明当前 ​​s[i]​​ 只需要用一个字符来表示一个数, 而不需要用两个字符来表示一个数.

class Solution {
public:
int romanToInt(string s) {
unordered_map<string, int> record{{"I", 1}, {"V", 5}, {"X", 10},
{"L", 50}, {"C", 100}, {"D", 500},
{"M", 1000}, {"IV", 4}, {"IX", 9},
{"XL", 40}, {"XC", 90}, {"CD", 400},
{"CM", 900}};
int res = 0;
for (int i = 0; i < s.size(); ++ i) {
if (i + 1 < s.size() && record.count(s.substr(i, 2))) {
res += record[s.substr(i, 2)];
++ i;
} else {
res += record[string(1, s[i])];
}
}
return res;
}
};

C++ 实现 2

两年前的代码.

class Solution {
private:
unordered_map<string, int> symbols = {
{"I", 1},
{"IV", 4},
{"V", 5},
{"IX", 9},
{"X", 10},
{"XL", 40},
{"L", 50},
{"XC", 90},
{"C", 100},
{"CD", 400},
{"D", 500},
{"CM", 900},
{"M", 1000},
};
public:
int romanToInt(string s) {
int res = 0;
for (int i = 0; i < s.size(); ) {
// s.substr(pos, len), 如果 len 超过了剩余的字符串的长度,
// 那么就返回剩余的字符串, 所以这里不需要对 i 的范围做检查
if (!symbols.count(s.substr(i, 2))) {
res += symbols[s.substr(i, 1)];
++ i;
}
else {
res += symbols[s.substr(i, 2)];
i += 2;
}
}
return res;
}
};