题目描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入:strs = ["flower","flow","flight"] 输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"] 输出:"" 解释:输入不存在公共前缀。
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i]
仅由小写英文字母组成
题目分析
在题解讨论区看到了大佬的画图解释:
来自这个大佬的笔记,谢谢谢谢谢谢!!!!
说人话 :
先设置一个ans字符串来装当前找到的最长前缀,在一开始,先让他等于strs(题目给的字符串数组)的第一个字符串,然后用ans 先与 strs[ 1 ] 中的每一个字符一个一个比,如果一样,继续,如果遇到不一样,停止退出,再拿着现在新的 ans 继续和 ans[ 2 ], ans[ 3 ]······ 依此类推,最后返回 ans。
那么现在让我们考虑特殊情况:
有没有可能ans找了半天最后什么也没有?——题目告诉了我们这个情况应该返回 “”
有没有可能strs字符串根本啥也没有?—— 题目告诉了我们这个情况应该返回 “”
好,
理论成立,实践开始!!!!!
代码(第一次报错版)
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0){
return ""; // 公共前缀为空,根据题目要求返回""
}
int j = 0;
String temp = strs[0]; // 令最长公共前缀 temp 的值为第一个字符串,进行初始化;
for(int i = 1; i < strs.length; i++){
// 从第二个字符串开始,逐个比较字符,更新公共前缀
for(; j < temp.length() && j < strs[i].length(); j++){
if(temp.charAt(j) != strs[i].charAt(j)){
break;
}
}
temp = temp.substring(0, j); // 更新公共前缀
if(temp.isEmpty()){
return ""; // 如果公共前缀为空,直接返回
}
}
return temp;
}
}
报错:测试项 :String[] strs = {"flower", "flow", "flight"}; 结果错误:flow,应该为 fl。
分析错误:没有将j重置
当我处理字符串数组时,我使用变量 `j` 来跟踪当前正在比较的字符的索引位置。在每次循环迭代中,我通过递增 `j` 来比较 `temp` 和 `strs[i]` 中的字符。这是一个有效的方法,但在我的初始代码中,`j` 并没有在处理下一个字符串 `strs[i]` 之前重置为0,因此它会继续从上一个字符串结束的位置继续增加。
例如,考虑这个情况:
String[] strs = {"flower", "flow", "flight"};
在处理第一个字符串 `"flower"` 时,`temp` 和 `"flow"` 的最长公共前缀是 `"flow"`,`j` 等于4。但在处理下一个字符串 `"flight"` 时,`j` 仍然保持为4,导致在 `"flow"` 的第四个字符之后继续比较,这可能会导致错误的结果。
通过在每次处理新字符串前将 `j` 重置为0,你可以确保每次都从新字符串的开头开始比较,而不是从上一个字符串结束的位置开始。这样可以确保 `j` 始终正确表示当前正在比较的字符的索引位置,从而得到正确的结果。
修改后的正确代码
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0){
return ""; // 公共前缀为空,根据题目要求返回""
}
String temp = strs[0]; // 令最长公共前缀 temp 的值为第一个字符串,进行初始化;
for(int i = 1; i < strs.length; i++){
int j = 0; // 重置 j 为0
// 从第二个字符串开始,逐个比较字符,更新公共前缀
for(; j < temp.length() && j < strs[i].length(); j++){
if(temp.charAt(j) != strs[i].charAt(j)){
break;
}
}
temp = temp.substring(0, j); // 更新公共前缀
if(temp.isEmpty()){
return ""; // 如果公共前缀为空,直接返回
}
}
return temp;
}
}
结果
总结
这道题要求找到一个字符串数组中的最长公共前缀。在解决这个问题时,你可以采取以下几个关键步骤和心得:
1. 初始公共前缀:通常,你可以将字符串数组中的第一个字符串作为初始的公共前缀,因为这是一个可行的起点。
2. 逐个比较字符:对于每个字符串数组中的其他字符串,逐个比较字符,更新公共前缀。你可以使用一个循环来逐个字符比较。
3. 及早退出:如果在比较过程中发现公共前缀为空,可以立即返回空字符串,因为没有公共前缀存在。
4. 保持索引位置:在比较字符时,要确保在下一个字符串比较之前重置索引位置。这防止了索引位置的累积增加,影响比较的结果。
5. 结束条件:比较字符时,可以使用两个条件来决定什么时候停止比较字符:a) 达到某个字符串的末尾,或b) 发现不匹配的字符。这将帮助你确定最长的公共前缀。
6. 时间复杂度:解决这个问题的时间复杂度通常为O(N*M),其中N是字符串数组的长度,M是最长公共前缀的长度。
7. 边界情况:始终要注意边界情况,如空字符串数组或空字符串的存在。
总之,这道题需要逐个比较字符,不断更新最长的公共前缀,并注意及早退出的条件。通过正确地维护索引位置,你可以得到正确的结果。