1、题目
2.1 解法1(使用hashmap,较慢)
- 如果检测包含两个字符,那么i += 2,检测包含1个字符 i++
- 注意hashmap的应用
- 这里有一个小问题:如果输入的字符串不全是罗马数字呢,所以else if()还需要添加条件,但是题目已经确定是罗马数字,所以不需要异常处理
class Solution {
public int romanToInt(String s) {
Map<String, Integer> map = new HashMap<>();
map.put("I", 1);
map.put("IV", 4);
map.put("V", 5);
map.put("IX", 9);
map.put("X", 10);
map.put("XL", 40);
map.put("L", 50);
map.put("XC", 90);
map.put("C", 100);
map.put("CD", 400);
map.put("D", 500);
map.put("CM", 900);
map.put("M", 1000);
int sum = 0;
for (int i = 0; i < s.length();) {
// 注意边界、获取值
if ((i+1) < s.length() && map.containsKey(s.substring(i, i+2))) {
sum += map.get(s.substring(i, i+2));
// 既然两个组队,就取掉这两个
i += 2;
} else {
sum += map.get(s.substring(i, i+1));
i++;
}
}
return sum;
}
}
时间复杂度O(n) (总共有n个字符,最坏条件下,即每个字符都查总共n,get值总共n, 那么就是3n,简称O(n)), 空间复杂度O(n)
2.2 解法2(掌握罗马数字规律)
@罗马数字的规律是:
- 通常情况下,罗马数字中小的数字在大的数字的右边(比如55, LV,因为十位肯定比个位大)
这时候now(此时的数肯定比pre小所以需要add) - 特殊情况是IV,大的数字在右边,所以应该减sub。
- 注意最后一个数字需要加
- switch方法比hashmap快
class Solution {
public int romanToInt(String s) {
int sum = 0;
int pre = getValue(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
int now = getValue(s.charAt(i));
if (now > pre) {
sum -= pre;
} else {
sum += pre;
}
pre = now;
}
sum += pre;
return sum;
}
public int getValue(char ch) {
// 条件语句
switch (ch) {
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;
}
}
}
== 时间复杂度O(n) (总共有n个字符),空间复杂度O(1)==