「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
做题
思路
这道题目有两种做法:
- 横向扫描。
- 纵向扫描。
横向扫描
先对比前两个字符串,比较出这两个字符串的最长公共前缀,可以称之为第一个最长公共前缀。
然后再拿第一个最长公共前缀和后面的字符串比较,直到比较到最后一个字符串,就可以得出最长公共前缀,最好情况下,第一个最长公共前缀为空字符串,可以直接返回。
纵向扫面
我会在后面踩过的坑里面讲述这个解法的具体。
举例演示
a = "111";
b = "111222";
c = "1122";
/**
* 先比较 a 和 b,它们的最长公共前缀为 "111"。
* 接着,拿 "111" 和 c 比较,它们的最长前缀为 "11"。
* 已经遍历完最后一个数组了,直接返回。
*/
除了遍历完最后一个数组后就直接返回结果,如果最长公共前缀的长度为 0,就直接返回空字符串。
运行的代码
class Solution {
public String longestCommonPrefix(String[] strs) {
int strLength = strs.length;
if(strs == null || strLength == 0 ){
// 我们需要 strs 的长度大于 0,才能使用 getPrefix 获取公共前缀,其他情况直接返回空字符串
return "";
}
// 设置第一个字符串为最长公共前缀
String prefix = strs[0];
for(int i = 1;i < strLength;i++){
prefix = getPrefix(prefix,strs[i]);
if(prefix.length() == 0){
return "";
}
}
return prefix;
}
// 获取公共前缀
private String getPrefix(String str1,String str2){
// 获取两个字符串的最小长度,可以避免判断指针是否到超出了两个字符串的长度
int minSize = Math.min(str1.length(),str2.length());
// 记录公共后缀的最后一个元素的下标
int index = 0;
while(index < minSize && str1.charAt(index) == str2.charAt(index)){
index++;
}
// 切割一个字符串返回
return str1.substring(0,index);
}
}
这里比较复杂的就是需要去写一个获取两个字符串公共前缀的方法,通过从左到右一位一位地比较,再根绝下标截取返回公共前缀。
踩过的坑
一开始,我就想着可以直接获取第一个字符串,然后从左到右判断剩下字符串的字符和第一个字符串的是否有相等的,如果相等,就直接拼接在结果后,不是就直接返回。
a = "123";
b = "123";
c = "134";
/**
* 先比较 a[0] 和 b[0],c[0] 是否相等,如果相等就拼接在结果后面。
* 再比较 a[1] 和 b[1],c[1] 是否相等。。。。
* 如果不相等,就直接返回当前的结果。
*/
于是,我写成了这样子:
public String longestCommonPrefix(String[] strs) {
int strSize = strs.length;
StringBuilder res = new StringBuilder();
String firstStr = strs[0];
int firstStrSize = firstStr.length();
for(int i = 0;i < firstStrSize;i++){
//循环次数为第一个字符串的长度
char item = firstStr.charAt(i);
for(int j=1;j < strSize;j++){
//循环次数为 strs 的长度
if(strs[j].charAt(i) == item){
res.append(item);
}else{
return res.toString();
}
}
}
return res.toString();
}
但是这里应该每个字符串都判断了是否相等才添加进去,运行出来的结果就会重复,结果如下。
于是,我把 res.append(item);往后提了,不过这里需要判断一下当前字符串的长度,最长公共前缀的长度肯定不能超过最短的一个字符串长度,所以又多了一种情况直接返回结果。
public String longestCommonPrefix(String[] strs) {
int strSize = strs.length;
StringBuilder res = new StringBuilder();
String firstStr = strs[0];
int firstStrSize = firstStr.length();
for(int i = 0;i < firstStrSize;i++){
//循环次数为第一个字符串的长度
char item = firstStr.charAt(i);
for(int j=1;j < strSize;j++){
//循环次数为 strs 的长度
if(strs[j].length() <= i || strs[j].charAt(i) != item){
return res.toString();
}
}
res.append(item);
}
return res.toString();
}
结果通过!
最后
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。