返回

探索共有的开端: 深入解析LeetCode 14. 最长公共前缀

后端

定义与示例

最长公共前缀问题可以定义为:给定一个字符串数组strs,求出一个公共的前缀,即字符串组中所有字符串共同具有的最长相同开头部分。如果没有共同的前缀,则返回空字符串“”。

例如:

  • 给定字符串数组strs = ["flower", "flow", "flight"],最长公共前缀为fl
  • 给定字符串数组strs = ["dog", "racecar", "car"],最长公共前缀为空字符串“”。

朴素算法

最简单的解决方法是比较字符串数组中的每个字符串。

func longestCommonPrefix(strs []string) string {
    if len(strs) == 0 {
        return ""
    }
    prefix := ""
    for i := 0; i < len(strs[0]); i++ {
        c := strs[0][i]
        for j := 1; j < len(strs); j++ {
            if len(strs[j]) <= i || strs[j][i] != c {
                return prefix
            }
        }
        prefix += string(c)
    }
    return prefix
}

更优方法

上面的朴素算法在某些情况下效率不高。当字符串数组中的字符串较长或较多时,算法的性能会受到影响。为了提高性能,我们可以使用分治法。

func longestCommonPrefix(strs []string) string {
    if len(strs) == 0 {
        return ""
    }
    return longestCommonPrefixHelper(strs, 0, len(strs) - 1)
}

func longestCommonPrefixHelper(strs []string, l, r int) string {
    if l == r {
        return strs[l]
    }
    mid := (l + r) / 2
    left := longestCommonPrefixHelper(strs, l, mid)
    right := longestCommonPrefixHelper(strs, mid + 1, r)
    return longestCommonPrefixOfTwoStrings(left, right)
}

func longestCommonPrefixOfTwoStrings(a, b string) string {
    prefix := ""
    for i, c := range a {
        if i >= len(b) || b[i] != c {
            break
        }
        prefix += string(c)
    }
    return prefix
}

这种分治方法将问题分成较小的子问题,然后递归地解决这些子问题。

总结

最长公共前缀问题是一个经典的编程挑战。通过朴素算法和分治法,我们可以高效地求解这个问题。希望本文对您的编程学习有所帮助。