力扣之最长公共前缀

754 阅读3分钟

问题描述

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

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

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

力扣原题目地址:leetcode.cn/problems/lo…

解决方案

思路分析

  • 对于这样的题目,首先要排除特殊情况,比如数组中只有一项,若只有一项,即这一项就是最长公共前缀。所以单独判断length是否等于1即可
  • 自然是公共前缀,那么我们可以取到字符串的单词去判断,当下的这个单词是否后续每一项都存在,所以我们会相当数组的every方法
  • 既然是公共前缀,即为,对应字符串开头的前缀,我们会想到字符串的startsWith方法
  • 比如数组为:['abc','abcd','abcde']。我们就直接以第一项为基准,取到第一项的第一个单词,a,然后看看这个a是不是后续每一项也是以a开头的。若是的,再往后取一位(这里要拼接变成ab),然后往后看一下,是不是每一项都是以ab开头的。
  • 如此循环,直到其中有一项不符合以ab开头的。当不符合某个条件的时候,退出循环,咱们就会相到while循环

代码如下

// 额外抽离出一个函数,用于判断
function startFn(strs, s) {
    let flag = strs.every((item) => {
        if (item.startsWith(s)) { // 必须每一项都要符合以xxx开头,才返回true
            return true
        }
    })
    return flag
}

var longestCommonPrefix = function (strs) {
    // 如果数组只有一项,那么最长公共前缀就是自身
    if (strs.length == 1) {
        return strs[0]
    }
    // 如果数组有多项,就要去遍历对比
    if (strs.length >= 2) {
        // 如果数组中第一项是空字符串的,那么所有的公共前缀就是空字符串
        // 这里需要注意空字符串没有第0项即: ""[0] === undefined
        if (!strs[0][0]) {
            return ''
        }
        // 排除空字符串的情况,我们在正常遍历即可
        let i = 0 // 这里的i是为了让第一项的单词累加
        let s = strs[0][i]
        while (startFn(strs, s)) {
            i = i + 1
            if (i > strs[0].length - 1) {
                // while内部的return说明已经全部循环完了(每一项长得都一样)
                return s
            } else {
                s = s + strs[0][i]
            }
        }
        // while外部的循环说明到某一个单词的时候,别的单词没有,即没有更大的最长公共前缀了
        return s.slice(0, -1) // 注意这里需要截取一下,多了一个单词。因为上方的s = s + strs[0][i] 多加了一次
    }

};

性能还可以截图如下

666.png

总结

对于这种类似的题目,首先把一些特殊情况排除掉,然后在思索的过程中,想想咱们可以使用到哪些方法api,最后按照思路来就行了。提交以后,如果不通过,再分析不通过的原因,进行代码优化即可