别灰心,好运早晚会降临的
—— 24.3.11
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 Ⅰ,2 Ⅱ,3 Ⅲ, 4 Ⅳ,5 Ⅴ,……,9 Ⅸ
思路
第一次遍历一个字符把符合值加到结果里,第二次遍历两个字符从结果中减去符合值。
Tips:charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
语法:public char charAt(int index)
参数:index -- 字符的索引。 返回值:返回指定索引处的字符。
class Solution {
public int romanToInt(String s) {
int result = 0;
for(int i = 0; i < s.length(); i++) {
switch(s.charAt(i)) {
case 'I':
result += 1;
break;
case 'V':
result += 5;
break;
case 'X':
result += 10;
break;
case 'L':
result += 50;
break;
case 'C':
result += 100;
break;
case 'D':
result += 500;
break;
case 'M':
result += 1000;
break;
}
}
for(int j = 0; j < s.length() - 1; j++) {
switch("" + s.charAt(j) + s.charAt(j+1)) {
case "IV":
case "IX":
result -= 2;
break;
case "XL":
case "XC":
result -= 20;
break;
case "CD":
case "CM":
result -= 200;
break;
}
}
return result;
}
}
方法二、直接switch对每一种情况都进行判断
思路
对传入的字符串转换为字符数组,对字符数组的每一位进行switch判断,由于已知当小的罗马数字出现在大的罗马数字左边,即是减法,出现在右边,即是加法,所以我们可以对字符数组的第i位和下一位第i+1位进行判断,然后根据switch的分组进行分类求和
Tips:Java中的Sring.toCharArray()方法是将字符串转换为字符数组的方法。它可以将一个字符串中的每个字符都放入一个字符数组中,并返回该字符数组。使用String.toCharArray()方法可以方便地对字符串中的每个字符进行操作,比如查找、替换、排序等
class Solution {
public int romanToInt(String s) {
int sum = 0;
char[] chars = s.toCharArray();
for(int i=0;i < chars.length;i++){
switch(chars[i]){
case 'I':sum+=1;break;
case 'V':if(i>0 && chars[i-1] == 'I')sum+=3;
else sum+=5;
break;
case 'X':if(i>0 && chars[i-1] == 'I')sum+=8;
else sum+=10;
break;
case 'L':if(i>0 && chars[i-1] == 'X')sum+=30;
else sum+=50;
break;
case 'C':if(i>0 && chars[i-1] == 'X')sum+=80;
else sum+=100;
break;
case 'D':if(i>0 && chars[i-1] == 'C')sum+=300;
else sum+=500;
break;
case 'M':if(i>0 && chars[i-1] == 'C')sum+=800;
else sum+=1000;
break;
}
}
return sum;
}
}
方法三 从右向左遍历,用pre记录前一个结点,与当前进行判断
从右往左遍历,如果左边的下一个罗马数字代表的数大于这个数代表的罗马数字,则最终值加上左边的罗马数字代表的数值,如果左边的下一个罗马数字代表的数值小于当前的罗马数字代表的数,则数值-左边的罗马数字代表的数值
Tips:charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
语法:public char charAt(int index)
参数:index -- 字符的索引。 返回值:返回指定索引处的字符。
class Solution {
public int romanToInt(String s) {
int sum=0;
int pre=0;
for(int i=s.length();i>0;i--){
char a=s.charAt(i-1);
int num=0;
switch(a){
case 'I':num=1;
break;
case 'V':num=5;
break;
case'X':num=10;
break;
case'L':num=50;
break;
case'C':num=100;
break;
case'D':num=500;
break;
case'M':num=1000;
break;
}
if(num<pre){sum-=num;}
else{sum+=num;}
pre=num;
}
return sum;
}
}