「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。
描述
罗马数字包含以下七种字符: 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 。
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
示例 1:
输入: s = "IX"
输出: 9
示例 2:
输入: s = "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 3:
输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= s.length <= 15
s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M')
题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
做题
这学习成本也太大了吧,还要先学习一下罗马数字,才能做这道算法,这还是简单题吗?
看了一会,我们需要知道的东西如下:
- 罗马数字是右加左減的。当数值比较小的字符遇到数值比较大的字符,就用大的减小的,就得到了这两个字符表达的数值;当数值比较大的字符遇到数值比较小的字符,就相加。更加简单一点地说,一个字符遇到数值比较大的字符,就会变成负数。
- 罗马数字只有这几个字符:I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。
因为我们只需要会读罗马数字就好了,不需要考虑如何构建一个罗马数字,所以题目种提到的很多特殊的、不符合题目要求的罗马数字我们也不用管,只要会读就行。
拿例题来模拟一下读数的过程, s = "MCMXCIV"(1994)
我们在遍历字符串的时候是从左往右的,这里我们也要按照从左往右的顺序。
M(1000)C(100)M(1000)X(10)C(100)I(1)V(5)
sum = 0;
sum += M(1000);
因为 C(100) 遇到了 M(1000),所以 C(-100)。
sum += C(-100);
sum += M(1000);
因为 X(10) 遇到了 C(100),所以 X(-10)。
sum += X(-10);
因为 I(1) 遇到了 V(5) ,所以 I(-1)。
sum += I(-1);
sum += V(5);
所以我们每次循环,都要拿到下一位的字符,用下一个字符的值比较判断现在的值的正负。
至于字符与数值的映射,莫得办法,要通过一个哈希表来转换,switch也行。
class Solution {
public int romanToInt(String s) {
int sum = 0;
int length = s.length();
for(int i = 0; i<length ;i++ ){
int currentValue = trans(s.charAt(i));
//int nextValue = trans(s.charAt(i+1));这里不能直接转换下一个字符,因为当处理最后一个字符时,没有下一个字符
if( i < length-1 && currentValue < trans(s.charAt(i+1))){
//当前字符小于下一个字符,变成负数
sum-=currentValue;
}else{
//最后一个字符也是直接相加
sum+=currentValue;
}
}
return sum;
}
private int trans(char c){
switch(c){
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
}
return 0;
}
}
最后
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。