方法一
一、思路
两层循环,第一层循环第一个字符串的各个字符,第二层循环strs除第一个字符串的其它字符串,比较当前字符是否和其他字符串对应位置的字符是否匹配
二、解题方法:
纵向扫描。纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。
三、代码:
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (!strs.size())//若字符串为空,则返回""
{
return "";
}
int length=strs[0].size();//第一个字符串的长度
int count=strs.size();//strs有几个字符串
//外层循环遍历第一个字符串的每个字符,内层循环遍历除第一个字符串外的其他字符串。在每次循环中,比较当前字符是否和其他字符串对应位置的字符不匹配,或者是否已经达到其他字符串的末尾。如果出现不匹配或达到末尾的情况,则返回当前已经匹配的前缀字符串,即第一个字符串的前缀子串 strs[0].substr(0, i)
for (int i=0;i<length;++i)//逐个遍历第一个字符串的各字母
{
char c=strs[0][i];//将第一个字符串的第i个字符传给c
for (int j=1;j<count;++j){//遍历除第一个字符串的其他字符串
if (i==strs[j].size() || c!=strs[j][i]){//如果找到不匹配的字符或到达字符串的末尾,则返回前缀字符串
return strs[0].substr(0,i);
}
}
}
return strs[0];//如果所有字符串都匹配,则返回第一个字符串
}
};
方法二
一、思路
假设将第一个字符作为公共前缀,直接符合则返回strs第一项,不符合则不断减少前缀,直到prefix为0
二、解题方法
通过.find函数查找strs从第二项开始的其它字符,如果查找到则返回第一个匹配子字符串的起始位置索引即0,如果没有找到则不断减少前缀的长度继续查找.
三、code
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.empty())
{
return "";
}
string prefix=strs[0];// 将第一个字符串作为初始前缀
//我们从第二个字符串开始遍历数组,并使用 find 函数来查找当前字符串是否以 prefix 开头。如果不是以 prefix 开头,则将 prefix 不断减少一个字符的长度,直到找到一个匹配的前缀或 prefix 变为空字符串。
for(int i=1;i<strs.size();++i)
{
while(strs[i].find(prefix) != 0)
{
prefix=prefix.substr(0,prefix.length()-1);// 逐渐减少前缀长度
if(prefix.empty())
{
return "";
}
}
}
return prefix;
}
};
=========================================================================
学到的知识:
① strs[i].find(prefix) != 0
strs[i].find(prefix)
是用于查找字符串 strs[i]
中是否以 prefix
开头的函数调用。find
函数返回的是一个位置索引,如果找到了匹配的子字符串,则返回第一个匹配子字符串的起始位置索引;如果未找到匹配的子字符串,则返回 string::npos
。
② prefix=prefix.substr(0,prefix.length()-1);
substr
函数用于从一个字符串中截取子串,接受两个参数:起始位置和截取长度。在这里,prefix.length() - 1
表示截取的长度,即将 prefix
的最后一个字符去除
例如,如果 prefix
的初始值为 "flower",那么 prefix.substr(0, prefix.length() - 1)
将得到 "flowe"。再次调用 prefix.substr(0, prefix.length() - 1)
将得到 "flow",以此类推,直到 prefix
变为空字符串为止。