【leetcode】 14. 最长公共前缀

51 阅读1分钟

leetcode-14.png

思路:取出第一个字符串来跟剩下的做对比,时间复杂度就是 O(nm),n为字符串数组strs的长度,m为第一个字符串的长度。

这里的indexOf也可以替换为 startWith

取最长的逐个比较

用第一个单词,从最长的部分逐个比较,如果能计数到strs数组的最后,那么此时就是最长的

var longestCommonPrefix = function (strs) {
    if (strs.length === 0) return ''
    if (strs.length === 1) return strs[0]
    let first = strs[0]
    for (let i = first.length; i > 0; --i) {
        // 从最长的字符串最先开始比较
        let tmp = first.slice(0, i)
        for (let j = 1; j < strs.length; ++j) {
            // 剩下的字符串开始的地方不是 tmp 为前缀
            // 直接 break 缩小 first 的范围
            if (strs[j].indexOf(tmp) !== 0) {
                break
            }
            // if (!strs[j].startsWith(tmp)) { break; }
            // 遍历完最后一个字符串,就可以 return tmp 了
            if (j === strs.length - 1) {
                return tmp
            }
        }
    }
    return ''
};

两两之间找出最大的前缀

两个字符串之间,找到最大的前缀,不断更新前缀

var longestCommonPrefix = function (strs) {
    if (strs.length === 0) return ''
    if (strs.length === 1) return strs[0]
    let prefix = strs[0]
    for (let i = 1; i < strs.length; ++i) {
        let j = 0
        while (j < prefix.length && j < strs[i].length && prefix[j] === strs[i][j]) {
            j++
        }
        // prefix 每次都更新到最大的限度,再与下一次的str[i]做比较
        prefix = prefix.slice(0, j)
        if (prefix === '') return ''
    }
    return prefix
};

顺序,逐个比较

这里为什么要在两个地方进行return呢?
当测试用例为['']的时候,是无法进入循环的,此时也就无法进行内层的return了

var longestCommonPrefix = function (strs) {
    let standard = strs[0];
    let i = 0;
    for (; i < strs[0].length; ++i) {
        for (let j = 0; j < strs.length; ++j) {
            if (strs[j][i] !== strs[0][i]) {
                return strs[0].slice(0, i);
            }
        }
    }
    return strs[0].slice(0, i);
};