【腾讯精选练习50题】14. 最长公共前缀(简单)

181 阅读2分钟

题目描述

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

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

示例1

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

输出:"fl"

示例2

输入:strs = ["dog","racecar","car"]

输出:""

解释:输入不存在公共前缀。

思路分析

  • 最先想到的就是先取俩个字符串,得到这两个字符串的最长公共前缀,然后最后公共前缀与后一个字符串,再比较最长公共前缀,以此类推,直到比较完成或无共前缀。这种就是横向的扫描

    str[0]  str[1] => prefix
    prefix  str[2] => 新prefix
    ...
    
  • 还有一种就是纵向的扫描,指针p从0开始依次增大,比较strs[0]、strs[1]....是否相等,从而判断公共前缀。是一种纵向的扫描。这里扫描的时候,不需要两两比较,所有的字符串和strs[0]比较就可以了

AC代码

横向扫描

// 执行用时:0 ms ,在所有 Go 提交中击败了100.00%的用户
// 内存消耗:2.3 MB, 在所有 Go 提交中击败了25.31%的用户
func longestCommonPrefix(strs []string) string {
    if strs == nil || len(strs) < 1 {
        return ""
    }

    if len(strs) == 1 {
        return strs[0]
    }

    rst := prefix(strs[0], strs[1])
    for i := 2; i < len(strs); i++ {
        p := prefix(rst, strs[i])
        if len(p) == 0 {
            return p
        }
        rst = p
    }
    return rst
}

// 得到两个字符串的公共前缀
func prefix(str1 string, str2 string) string {
    len1 := len(str1)
    len2 := len(str2)

    var length int
    if len1 < len2 {
        length = len1
    } else {
        length = len2
    }

    for i := 0; i < length; i++ {
        if str1[i] != str2[i] {
            return str1[0:i]
        }
    }
    return str1[0:length]
}

纵向扫描

// 执行用时:0 ms ,在所有 Go 提交中击败了100.00%的用户
// 内存消耗:2.3 MB, 在所有 Go 提交中击败了87.00%的用户
func longestCommonPrefix(strs []string) string {
    if strs == nil || len(strs) < 1 {
        return ""
    }

    for i := 0; i < len(strs[0]); i++ {
        for j := 1; j < len(strs); j++ {
            if len(strs[j])-1 < i || strs[0][i] != strs[j][i] {
                return strs[0][0:i]
            }
        }
    }
    return strs[0]
}

总结

  • 有的问题,想起来比较简单,但是写起来还是很多细节需要注意的。