13. 罗马数字转整数
1 题目描述
- 题目链接:13. 罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做?II?,即为两个并列的 1 。12 写做?XII?,即为?X?+?II?。 27 写做??XXVII, 即为?XX?+?V?+?II?。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做?IIII,而是?IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为?IX。这个特殊的规则只适用于以下六种情况:
I?可以放在?V?(5) 和?X?(10) 的左边,来表示4和9。X?可以放在?L?(50) 和?C?(100) 的左边,来表示40和?90。?C?可以放在?D?(500) 和?M?(1000) 的左边,来表示?400和?900。
给定一个罗马数字,将其转换成整数。
示例1:
输入: s = “III”
输出: 3
示例2:
输入: s = “IV”
输出: 4
示例3:
输入: s = “IX”
输出: 9
示例4:
输入: s = “LVIII”
输出: 58
示例5:
输入: s = “MCMXCIV”
输出: 1994
2 思路
- 直接对每一种情况进行分类判断,当查询到
CD、CM、XL、XC、IV、IX等情况时进行特殊处理,并将索引移到下下个位置,即同时处理当前位置和下一个位置;否则则直接将当前位置代表的数字加到答案中。
class Solution {
public:
int romanToInt(string s) {
int res = 0, n = s.length();
for(int i = 0; i < n; ++i){
if(s[i] == 'C'){
if(i+1 < n){
if(s[i+1] == 'D'){
++i;
res += 400;
continue;
}else if(s[i+1] == 'M'){
++i;
res += 900;
continue;
}
}
res += 100;
}else if(s[i] == 'X'){
if(i+1 < n){
if(s[i+1] == 'L'){
++i;
res += 40;
continue;
}else if(s[i+1] == 'C'){
++i;
res += 90;
continue;
}
}
res += 10;
}else if(s[i] == 'I'){
if(i+1 < n){
if(s[i+1] == 'V'){
++i;
res += 4;
continue;
}else if(s[i+1] == 'X'){
++i;
res += 9;
continue;
}
}
res += 1;
}else if(s[i] == 'M'){
res += 1000;
}else if(s[i] == 'D'){
res += 500;
}else if(s[i] == 'L'){
res += 50;
}else{
res += 5;
}
}
return res;
}
};
- 上述的代码些许重复,按照相同的思路,只要查找到小值在大值前边,说明此时为特殊情况,则将
s[i+1]-s[i]对应的值加到答案中,否则将s[i]对应的值加到答案。这里用一个哈希表来实现字符到数字的映射。
class Solution {
unordered_map<char, int> m = {
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
public:
int romanToInt(string s) {
int res = 0, n = s.length();
for(int i = 0; i < n; ++i){
if(i+1 < n && m[s[i]] < m[s[i+1]]){
res += m[s[i+1]] - m[s[i]];
++i;
}else{
res += m[s[i]];
}
}
return res;
}
};