力扣刷题简单题100道其四——14. 最长公共前缀(Java)

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 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. 边界情况:始终要注意边界情况,如空字符串数组或空字符串的存在。

总之,这道题需要逐个比较字符,不断更新最长的公共前缀,并注意及早退出的条件。通过正确地维护索引位置,你可以得到正确的结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值