这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战
罗马数字转整数
该题出自力扣的13题——罗马数字转整数,题解是自己做的
审题
整道题其实就是一个意思:给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
由字符串转成整型数字
-
常规逻辑的话,正面遍历,可能会比较麻烦难搞
- 因为罗马数字的特性——IV是4,也就是说小的在左边的情况下需要减
- 这也是需要判断的点,相对会比较繁琐
-
如果从后面去遍历的话,情况就会比较清晰
- 从后往前遍历,如果是更大的或者同级则相加更新
- 记录当前的罗马数字对应的值,作为下次的比较
- 如果是小的则相减
-
时间复杂度是O(n),空间复杂度会较高,虽然是O(1),但还是开辟了额外的空间去存储罗马数字
编码
Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('I', 1);
put('V', 5);
put('X', 10);
put('L', 50);
put('C', 100);
put('D', 500);
put('M', 1000);
}};
public int romanToInt(String s) {
//从右边开始遍历,如果是更大的或者同级则相加更新;如果是小的则相减
int lengtn = s.length();
int num = 0;
int index = 0;
for (int i = lengtn-1;i>=0;i--){
char c = s.charAt(i);
if (map.get(c)>= index){
index = map.get(c);
num = num + index;
}else {
index = map.get(c);
num = num - index;
}
}
return num;
}
彩蛋
其实,可以有相对更好的解法,虽然并无伤大雅,但是却可以提高空间复杂度。在上述的解法中,因为要额外开辟空间给HashMap,又因为HashMap在少数据量的情况下,性能并是最好的。
- 可以使用switch取代Hashmap
public static Integer numChange(Character 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;
default:return 0;
}
}
- 总体来说是优化了三次
- 第一次是把HashMap放在里层,等于是每次调用再初始化,也就是类似单例中懒汉的模式
- 第二次是做了全局,类似单例中的饿汉模式,空间小了了0.2MB
- 第三次就是调用switch,时间少了一半,空间也少了