大家好,我是怒码少年小码。
最长公共前缀
LeetCode 14:编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例:
- 输入:strs = [“flower”,“flow”,“flight”]
- 输出:“fl”
方法一:
分析:最先想到的应该就是选择一个字符串作为基点,和之后的字符串逐个比较了,就像竖向比较一样:
代码如下:
这段代码实现了一个函数 longestCommonPrefix
,用于找出一组字符串中最长的公共前缀。下面对代码进行详细解释:
string longestCommonPrefix(vector<string>& strs) {
if(!strs.size()){
return "";
}
int length = strs[0].size();
int count = strs.size();
for(int i=0 ; i< length;i++){
char c = strs[0][i];
for(int j = 1;j<count;j++){
if(i==strs[j].size() || strs[j][i] != c){
return strs[0].substr(0,i);
}
}
}
return strs[0];
}
if(!strs.size())
:首先,代码检查传入的字符串向量strs
是否为空。如果为空,则直接返回一个空字符串,因为没有任何字符串需要进行比较与查找公共前缀。int length = strs[0].size();
:接下来,代码获取第一个字符串的长度作为length
变量的值,以确定最长公共前缀的最大可能长度。int count = strs.size();
:获取传入的字符串向量strs
的大小,表示包含的字符串数量。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() || strs[j][i] != c)
:在每次循环内部,首先判断索引i
是否已经超出某个字符串的长度,或者当前字符串的第i
个字符与第一个字符串的第i
个字符是否相等。- 如果索引
i
已经超出了某个字符串的长度,或者当前字符串的第i
个字符与第一个字符串的第i
个字符不相等,表示已经找到了最长公共前缀的结束位置,即当前索引i
的位置。此时,函数使用substr(0,i)
返回第一个字符串的前i
个字符作为最长公共前缀。 - 否则,继续比较下一个字符串的第
i
个字符。
- 如果索引
- 如果没有在内层循环中返回最长公共前缀,说明第一个字符串是所有字符串的公共前缀,因此返回第一个字符串即可。
substr(0, i)
是一个字符串的成员函数,用于提取从索引 0 开始,长度为 i
的子字符串。在这段代码中,如果找到了最长公共前缀的结束位置(索引 i
),函数使用 substr(0,i)
来提取第一个字符串的前 i
个字符作为最长公共前缀。
方法二:
分析:先找到数组中前两个字符串的最长公共前缀,然后再比较第二个字符串和第三个字符串的最长公共前缀,看看是否需要缩小,直到数组遍历完毕或者最长公共前缀已经为零了。
代码我使用Java写的:
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0){
return "";
}
String prefix = strs[0];
int count = strs.length;
for(int i =1;i<count;i++){
prefix = longestCommonPrefix(prefix,strs[i]);
if(prefix.length() == 0){
break;
}
}
return prefix;
}
public String longestCommonPrefix(String str1,String str2){
int length = Math.min(str1.length(),str2.length());
int i =0;
while(i<length && str1.charAt(i) == str2.charAt(i)){
i++;
}
return str1.substring(0,i);
}
首先,代码判断了输入参数是否为空或数组长度是否为0,如果是,则返回空字符串。接下来,定义了一个变量prefix
,并将其初始化为数组的第一个字符串,作为初始化前缀。同时,定义了一个计数变量count
,将其赋值为数组的长度。
然后,通过一个循环遍历数组中的每个字符串(从第二个字符串开始),将当前前缀和当前字符串传递给另一个方法longestCommonPrefix,获取新的前缀。在这个方法中,代码首先计算了两个字符串的最小长度,因为最长公共前缀不能超过这个最小长度。
然后,通过一个while循环,从字符串的第一个字符开始逐个比较两个字符串的字符是否相等,直到遇到不相等的字符或达到最小长度为止。循环结束后,返回前缀字符串,它就是两个字符串的最长公共前缀。
longestCommonPrefix(String[] strs)
方法中,每次获取了新的前缀后,代码会判断新的前缀的长度是否为0,如果是,则终止循环。最后,返回最终的前缀作为结果。
它的时间复杂度是O(n*m),其中n是字符串的平均长度,m是数组中字符串的数量。