不知哪个大佬说过: 关于字符串的题都可以用指针或哈希解决。
罗马数字转数字:
思想: 我们能观察到规律: 一般情况下,表示大的字母在前,小字母在后;
特殊情况下,小字母会在大字母之前,但是相应的,得到的值会是大字母-小字母
所以,我们可以用哈希表映射大小,利用哈希表比较所给罗马字母,一般情况直接+该对应值,否则-该对应值
class Solution { public: //用哈希表映射字符,处理特殊条件:前字母<后字母==前字母变负数 int romanToInt(string s) { map<char,int> hash; hash['I'] = 1; hash['V'] = 5; hash['X'] = 10; hash['L'] = 50; hash['C'] = 100; hash['D'] = 500; hash['M'] = 1000; int sum = 0; for(int i = 0;i<s.size();++i) { if(hash[s[i]] < hash[s[i+1]]) { sum-=hash[s[i]]; continue; } sum+=hash[s[i]]; } return sum; } };
数字转罗马数字:
思想 : 这道题关键是用贪心算法,尽量使用少的字母来表示最大的数,然后要观察规律,从大到小找到那些必要罗马数(该罗马数不能被前面的罗马数相加得到)
所以,我们先建立必要罗马数表,再用贪心思想进行计算。
class Solution { public: //贪心算法:尽量使用最少的字符,从最大的开始 string intToRoman(int num) { map<int,string> mapRom = {{1,"I"},{4,"IV"},{5,"V"},{9,"IX"}, {10,"X"},{40,"XL"},{50,"L"}, {90,"XC"}, {100,"C"},{400,"CD"},{500,"D"}, {900,"CM"}, {1000,"M"} }; auto r_iter = mapRom.rbegin(); string ret; while(num>0 && r_iter!=mapRom.rend()) { if(num >= r_iter->first) { ret += r_iter->second; num-= r_iter->first; } else r_iter++; } return ret; } };