题目描述
考察点
逻辑分析能力
第一次:2022年12月8日15:24:16
解题思路
分析能力有待提高
代码展示
class Solution {
public int romanToInt(String s) {
int result = 0;
int special = 0;
// 当前下标
int i = 0;
// 下标的下一位置
int j = 0;
// 当前的下标还在字符串里面
while (i < s.length()) {
// 求出下标的下一位置
j = i + 1;
// 如果下标的下一个位置 到达 字符串的末尾了
if (j == s.length()){
// 当前的值 + 当前字符对应的值
result += charToNum(s.charAt(i));
// 跳出循环
break;
}
// 判断当前下标的字符是否能够与下一个字符 组成特殊情况
StringBuilder stringBuilder = new StringBuilder();
special = specialCondition(stringBuilder.append(s.charAt(i)).append(s.charAt(j)).toString());
// 如果能够组成特殊情况
if (special != 0){
// 当前的值 + 特殊情况的值
result += special;
// 下标跳一位
i = i + 2;
}
// 不能够组成特殊情况
else {
// 当前的值 + 当前字符对应的值
result += charToNum(s.charAt(i));
// 下标移到下一位
i ++;
}
}
return result;
}
/**
* 特殊的规则适用的六种情况
*
* @param s 字符串
* @return int 结果
*/
private int specialCondition(String s) {
switch (s) {
case "IV": return 4;
case "IX": return 9;
case "XL": return 40;
case "XC": return 90;
case "CD": return 400;
case "CM": return 900;
default: return 0;
}
}
/**
* 字符转数字
*
* @param i 字符
* @return int 数字
*/
private int charToNum(char i) {
switch (i) {
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;
default: return 0;
}
}
}
测试用例
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.romanToInt("MCMXCIV"));
}
优秀的解题思路
1. 总结规律
作者:donespeak
按照题目的描述,可以总结如下规则:
- 罗马数字由 I,V,X,L,C,D,M 构成;
- 当小值在大值的左边,则减小值,如 IV=5-1=4;
- 当小值在大值的右边,则加小值,如 VI=5+1=6;
- 由上可知,右值永远为正,因此最后一位必然为正。
一言蔽之,把一个小值放在大值的左边,就是做减法,否则为加法。
在代码实现上,可以往后看多一位,对比当前位与后一位的大小关系,从而确定当前位是加还是减法。当没有下一位时,做加法即可。
也可保留当前位的值,当遍历到下一位的时,对比保留值与遍历位的大小关系,再确定保留值为加还是减。最后一位做加法即可。
2. 字符串替换
在这个解题思路链接的评论区中看到的。
妙蛙种子给妙趣角开门,妙到家了
class Solution {
public int romanToInt(String s) {
s = s.replace("IV","a");
s = s.replace("IX","b");
s = s.replace("XL","c");
s = s.replace("XC","d");
s = s.replace("CD","e");
s = s.replace("CM","f");
int res = 0;
for (int i = 0; i < s.length(); i++) {
res += getValue(s.charAt(i));
}
return res;
}
public int getValue(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;
case 'a': return 4;
case 'b': return 9;
case 'c': return 40;
case 'd': return 90;
case 'e': return 400;
case 'f': return 900;
}
return 0;
}
}
2023-8-14 09:51:49
自己写出来了,有进步。
这道题关键就是看懂题目的意思,通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例
。
class Solution {
public int romanToInt(String s) {
int pre = 0;
int result = 0;
while (pre < s.length()) {
int preNum = getNum(s.charAt(pre));
int last = pre + 1;
if (last < s.length() && preNum < getNum(s.charAt(last))) {
result = result + (getNum(s.charAt(last)) - preNum);
pre = last + 1;
}else {
result = result + preNum;
pre++;
}
}
return result;
}
public int getNum(char i) {
if (i == 'I') {
return 1;
} else if (i == 'V') {
return 5;
} else if (i == 'X') {
return 10;
} else if (i == 'L') {
return 50;
} else if (i == 'C') {
return 100;
} else if (i == 'D') {
return 500;
} else {
return 1000;
}
}
}