题目描述
【leetcode】14. 最长公共前缀(Longest Common Prefix)
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
第一次解答
看到题目直觉就是挨个遍历完所有字符串的第1元素,第2元素,第3元素…直到有不同,或者某个字符串遍历完毕。
判断是否共同前缀,想法是:如果大家是共同前缀,那么都应该一样,所以随便取某个字符串的元素作为基准,大家与这个基准比较就好了。
// 思路:
// 假设strs的size为n
// 遍历strs的每个字符串,第1到n-1的字符串的第i个字符
// 分别减去第0个字符串的第i个字符
// 若都为0,则该字符为共同前缀,添加到前缀prefix中。
// 退出条件为:
// 有某个字符串到了size的尽头。
// test case:
// ["flower","flow","flight"]
// ["dog","racecar","car"]
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
std::string prefix = "";
if(0 == strs.size())
return prefix;
// 共同prefix最长不会超过strs最短字符串的长度
prefix.reserve(strs[0].size());
// 以第0个字符串的第i个字符为基准,逐一对比
for(int i=0; i<strs[0].size(); ++i){
char str_a = strs[0][i];
int j=1;
// 遍历所有字符串的第i个字符
for(; j<strs.size(); ++j){
char str_b = strs[j][i];
// 如果有字符串的第i个字符与第0个字符串的第i个字符不相等,退出循环
if(str_b - str_a != 0)
break;
}
// 若所有字符串的第i个字符相等,则j必定满足条件
if(j >= strs.size()){
// 添加这个字符到前缀
prefix.append(1, str_a);
}
}
return prefix;
}
};
第二次解答
解答一算是比较稳扎稳打,也比较好理解。看了别人的答案发现,其实有些中间的临时变量可以省略,想着这样能节省一点点空间,于是又改了下代码。这一改就是error,仔细分析才发现,为了省下这点空间,需要多出许多边界判断,代码很容易出bug,最后得到的结果跟解答一差不多,有点得不偿失。
// 思路:
// 假设strs的size为n
// 遍历strs的每个字符串,第1到n-1的字符串的第i个字符
// 分别减去第0个字符串的第i个字符
// 若都为0,则该字符为共同前缀,添加到前缀prefix中。
// 退出条件为:
// 有某个字符串到了size的尽头。
// 注意:
// strs.size() 为空的情况
// strs[0].size() 为空的情况
// strs.size() 为1的情况,即只有一个字符串
// test case:
// ["flower","flow","flight"]
// ["dog","racecar","car"]
// ["aca","cba"]
// ["a"]
// ["aaa","aaa"]
using namespace std;
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(0 == strs.size())
return "";
if(0 == strs[0].size())
return "";
if(1 == strs.size())
return strs[0];
// 以第0个字符串的第i个字符为基准,逐一对比
int i=0;
for(; i<strs[0].size(); ++i){
char str_a = strs[0][i];
// 遍历所有字符串的第i个字符
for(int j=1; j<strs.size(); ++j){
char str_b = strs[j][i];
// 如果有字符串的第i个字符与第0个字符串的第i个字符不相等,函数返回
if(str_b != str_a){
return (0 == i ? "" : strs[0].substr(0, i));
}
}
}
return (0 == i ? "" : strs[0].substr(0, i));
}
};
结果: