2019年5月31日 第四天练习(13罗马数字转整数)+2019年6月3日 第五天练习(14最长公共前缀)
13.罗马数字转整数
题目的大致意思就是将罗马数字转换成对应的整数。我的想法是依次读出字符,然后变成相应的数字就ok了,但这里有一个难点是如何进行”小数位置在大数左边“这种行为的处理?
解决方法
要不一次读取两个字符,如果左边字符小于右边字符,则只输出左边字符,若左边字符大于右边字符,则二者一起输出。
首先要解决的是如何一次读取两个字符?
方法一: 还是用字符串的数组来判断
class Solution { public: int romanToInt(string s) { int sum = 0; for(int i = 0; i < s.size(); ++i) { if(s[i] == 'I') { if(i != s.size() - 1 && (s[i+1] == 'V' || s[i+1] == 'X')) { sum -= 1; } else sum += 1; } if(s[i] == 'V') sum += 5; if(s[i] == 'X') { if(i != s.size() - 1 && (s[i+1] == 'L' || s[i+1] == 'C')) { sum -= 10; } else sum += 10; } if(s[i] == 'L') sum += 50; if(s[i] == 'C') { if(i != s.size() - 1 && (s[i+1] == 'D' || s[i+1] == 'M')) { sum -= 100; } else sum += 100; } if(s[i] == 'D') sum += 500; if(s[i] == 'M') sum += 1000; } return sum; } };
执行后:
方法二 调用string中的一个函数方法substr()进行实现,这样可以实现一次读取两个字符。
string substr (size_t pos = 0, size_t len = npos) const
主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度或超出了源字符串的长度,则子字符串将延续到源字符串的结尾。
所以实现的代码如下:
class Solution { public: int romanToInt(string s) { if(s=="") return 0; int sum=0; int len=s.size(); int i=0; while(i<len) { if(s.substr(i,2)=="IV") { sum=sum+4; i=i+2; continue; } if(s.substr(i,2)=="IX") { sum=sum+9; i=i+2; continue; } if(s.substr(i,2)=="XL") { sum=sum+40; i=i+2; continue; } if(s.substr(i,2)=="XC") { sum=sum+90; i=i+2; continue; } if(s.substr(i,2)=="CD") { sum=sum+400; i=i+2; continue; } if(s.substr(i,2)=="CM") { sum=sum+900; i=i+2; continue; } if(s.substr(i,1)=="I") { sum=sum+1; i=i+1; continue; } if(s.substr(i,1)=="V") { sum=sum+5; i=i+1; continue; } if(s.substr(i,1)=="X") { sum=sum+10; i=i+1; continue; } if(s.substr(i,1)=="L") { sum=sum+50; i=i+1; continue; } if(s.substr(i,1)=="C") { sum=sum+100; i=i+1; continue; } if(s.substr(i,1)=="D") { sum=sum+500; i=i+1; continue; } if(s.substr(i,1)=="M") { sum=sum+1000; i=i+1; continue; } } return sum; } };
执行后:发现调用函数并不如直接用数组进行执行的效率更高些
后来看到别人的代码,发现在C++语言中用哈希算法构造对应关系也可以完成,比如某位大神写的
class Solution { public: int romanToInt(string s) { int result=0; map<char,int> myMap; myMap.insert(map<char,int>::value_type('I',1)); myMap.insert(map<char,int>::value_type('V',5)); myMap.insert(map<char,int>::value_type('X',10)); myMap.insert(map<char,int>::value_type('L',50)); myMap.insert(map<char,int>::value_type('C',100)); myMap.insert(map<char,int>::value_type('D',500)); myMap.insert(map<char,int>::value_type('M',1000)); for(int i=0;i<s.length();i++){ if(myMap[s[i]]>=myMap[s[i+1]]) result+=myMap[s[i]]; else{ result+=myMap[s[i+1]]-myMap[s[i]]; i++; } } return result; } };
但这个效率…函数用的太多的过,但代码简洁,易于增长
14 最长公共前缀
首先忏悔,六月一日二日过儿童节太快乐了,不仅导致31日的没有发出去还耽误了两天没有写…我忏悔==。但6.1日还顺便考了个试,EMMMM考的人工智能的一个训练营,突然发现要学机器学习和人工智能,是很要数学功底的啊啊啊啊,照样是题都看不懂,不说了都是泪,继续好好刷题吧…
今天继续刷easy类的题,这道题的大致意思就是数组里存几个字符串,判断这些字符串的公共前缀是什么。
好吧,看到第一眼毫无思路,觉得是要一个字符一个字符拿出来比较,总不能有几个字符串建立几个栈或者指针吧==。
看了答案,果然不是,有以下几种思路(因为不会,只能照搬了,学习了)
方法一:水平扫描法
首先,我们将描述一种查找一组字符串的最长公共前缀 LCP(S1…Sn)的简单方法我们将会用到这样的结论:
LCP(S1…Sn)=LCP(LCP(LCP(S 1,S2),S3),…S n )
我个人感觉这个方法很容易理解,而且也很容易实现,所以用代码敲一敲试试:
class Solution { public: string longestCommonPrefix(vector<string>& strs) { if(strs.empty()) return""; string s=strs[0]; for(int i=1;i<strs.size();i++){ //要注意数组中只有size()方法,没有length()方法。 for(int j=0;j<s.length();j++){ if(s[j]==strs[i][j]) continue; else{ s.erase(j); break; } } } return s; } };
方法二:水平扫描
想象数组的末尾有一个非常短的字符串,使用方法一依旧会进行S 次比较。优化这类情况的一种方法就是水平扫描。我们从前往后枚举字符串的每一列,先比较每个字符串相同列上的字符(即不同字符串相同下标的字符)然后再进行对下一列的比较。
class Solution { public: string longestCommonPrefix(vector<string>& strs) { if (strs.empty()) return ""; for (int i = 0; i < strs[0].length() ; i++){ char c = strs[0].at(i); for (int j = 1; j < strs.size(); j ++) { if (i == strs[j].length() || strs[j].at(i) != c) return strs[0].substr(0, i); } } return strs[0]; } };
可以看到执行用时以最短的字符串为标准,执行时间大大减少,但是若字符串长度相等,则这个方法效率并不会很明显。
- leetcode第三天 9回文数、13罗马数字转整数、14最长公共前缀
- leetcode-腾讯精选练习(50 题)python #14最长公共前缀
- 某公司面试题:最长顺子;输入很多个整数(1<=数值<=13),返回其中可能组成的 最长的一个顺子(顺子中数的个数代表顺的长度); 其中数字1也可以当作14用
- 14.最长公共前缀
- LeetCode 13 罗马数字转整数(字符串)
- LeetCode--13. 罗马数字转整数(Roman to Integer)
- leetcode的python实现 刷题笔记13: 罗马数字转整数
- LeetCode14:最长公共前缀
- leetcode-14-求字符串数组最长公共前缀
- LeetCode 14. 最长公共前缀
- 算法练习六: 最长公共前缀
- LeerCode 题 - 14. 最长公共前缀
- Leetcode14. 最长公共前缀
- leetcode14. 最长公共前缀
- Leetcode 13 Roman to Integer 罗马数字转整数
- LeetCode 14 Longest Common Prefix(最长公共前缀)(String)
- Leet Code 14 Longest Common Prefix - 最长公共前缀 - Java
- Leetcode : 13 罗马数字转整数
- Leet Code 13 Roman to Integer - 罗马数字转成整数 - Java
- 14.最长公共前缀