力扣算法系列第13题
前言
采用Hashmap的数据结构来实现罗马数字转整数,从算法效率,即时间复杂度与空间复杂度上而言,并不是一个比较合适的选择。笔者只是希望采用Hashmap这样的结构,来深化对基础数据结构的掌握与运用。
算法思想
从给定的字符串的末尾开始,如果第一个字符所映射的值小于第二个字符所映射的值,则将两个字符所映射的值,加在总值上。反之,则将宗值减第二个值所映射的值。
数据结构
前言:Hashmap本为键值对的方式来存储数据结构,即key-value的方式。在Hashmap集合中,key值是不可以重复的。笔者本意是重温Hashmap的基础知识,故而采用了Integer---String的结构,从而使用了根据value查找key的方法。这是可以优化的。
代码展示(已经测试通过)
class Solution {
public int romanToInt(String s) {
Map<Integer,String> map = new HashMap<>();
map = getMap();
if (s.length() == 1){
return getKey(map,s);
}else if (s.length() == 2){
return getKey(map,s.substring(0,1)) >= getKey(map,s.substring(1,2)) ? getKey(map,s.substring(1,2)) + getKey(map,s.substring(0,1)) : getKey(map,s.substring(1,2)) - getKey(map,s.substring(0,1));
}else{
int num = getKey(map,s.substring(s.length()-1));
int prev = 0;
int now = 0;
for (int i = s.length()-2; i >= 1; i--) {
now = getKey(map,s.substring(i,i+1));
prev = getKey(map,s.substring(i+1,i+2));
num += now >= prev? now : -now;
}
num += getKey(map,s.substring(0,1)) >= now ? getKey(map,s.substring(0,1)):-getKey(map,s.substring(0,1));
return num;
}
}
private static Map<Integer,String> getMap(){
Map<Integer,String> map = new HashMap<>();
map.put(1,"I");
map.put(4,"IV");
map.put(5,"V");
map.put(9,"IX");
map.put(10,"X");
map.put(40,"XL");
map.put(50,"L");
map.put(90,"XC");
map.put(100,"C");
map.put(400,"CD");
map.put(500,"D");
map.put(900,"CM");
map.put(1000,"M");
return map;
}
public static Integer getKey(Map<Integer,String> map,String value){
Integer key = null;
for (Map.Entry<Integer,String> entry : map.entrySet()){
if (value.equals(entry.getValue())){
key = entry.getKey();
break;
}
}
return key;
}
}
尾声
正如笔者先前所声明,采用Hashmap的解法,并不是追求时间与空间复杂度,而是牺牲了算法效率只为了掌握Hashmap。 这也就意味着存在很多可以改进的地方
例如:改变Hashmap的结构,采用String-Integer的方式,就可以根据key来获取value(根据value获得key,需要遍历Hashmap集合,算法效率大受影响)。此外,笔者在Hashmap集合中,添加的二字符的键值对,其实也并无必要,可以去除。如果不采用Hashamap结构,还可以通过swich---case的控制语句来获得字符所对应的映射值,这里就暂时不做代码实现了。