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;
}
};