一、概述
给出n个字符串,返回它们的最长相同前缀。
我知道我的方法肯定是最蠢的,按列找,最差是O(n^2)的时间复杂度,但自己没有想到更好的。
我猜较好的方法肯定用了剩余的空间,否则我的空间复杂度不会这么低。
二、分析
1、我的思路
大模拟,按列遍历直到找到不同或者到达最短字符串的最后一位。
有一个地方要注意:
while(j<strs.size()&&i<strs[j].size()&&first==strs[j][i])
我的退出循环语句是这样的,三个&&来判断,一定要把判断j是否是最后一行放在首位,因为C++判断是按从前到后的,第一个判断成立,那就不去看第二个第三个了,如果判断j不在首位,那么当最后一行之后,访问j会报错。
其他就没有要注意的地方。
2、较好的方法
好个屁,我看了一下discussion的代码,时间复杂度也都是O(n^2),只是有一个细节做了优化,直接从12ms到了8ms,如下:
改了两个地方,我原来循环中都是直接调用strs.size()函数的,因此最多调用n^2次函数,把这个函数值存起来就好了。
三、总结
对于会多次调用的函数值,用一个变量存起来可以极大减少时间。
多个判断条件,要注意先后顺序。
PS:代码如下:
1、我的代码
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string ans="";
if(strs.size()==0)
return ans;
char first;
for(int i=0;i<strs[0].size();i++)
{
first=strs[0][i];
int j=1;
while(j<strs.size()&&i<strs[j].size()&&first==strs[j][i])
j++;
if(j==strs.size())
ans+=first;
else
return ans;
}
return ans;
}
};
2、我的代码(快)
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string ans="";
if(strs.size()==0)
return ans;
else if(strs.size()==1)
return strs[0];
char first;
int MAX=strs[0].size();
int num=strs.size();
for(int i=0;i<MAX;ans+=first,i++)
{
first=strs[0][i];
for(int j=1;j<num;j++)
{
if(strs[j][i]!=first)
return ans;
}
}
return ans;
}
};