返回

LeetCode算法14:寻找最长公共前缀的详细指南

后端

前言

作为一名经验丰富的程序员,您可能会遇到一个常见的编程面试问题:LeetCode算法14“寻找最长公共前缀”。该算法要求您找到一组字符串中最长的公共前缀。乍一看,它似乎很简单,但如果您不掌握正确的技巧,它可能会变得棘手。

分步指南

1. 定义公共前缀

公共前缀是指一组字符串共享的开头部分。例如,字符串“flower”、“flow”、“flight”的公共前缀是“fl”。

2. 暴力破解法

最简单的方法是使用暴力破解法。对于每个字符串,从第一个字符开始比较,直到遇到第一个不匹配的字符。将最长的匹配前缀记录为公共前缀。

def find_longest_common_prefix(strs):
    if not strs:
        return ""
    
    prefix = ""
    for i in range(len(min(strs))):
        c = strs[0][i]
        if all(s[i] == c for s in strs):
            prefix += c
        else:
            break
    
    return prefix

3. 优化方法:分治法

分治法将字符串分成两半,然后递归地在每一半中寻找最长公共前缀。最后,合并两半的公共前缀。

def find_longest_common_prefix_divide_and_conquer(strs):
    if not strs:
        return ""
    
    def divide_and_conquer(start, end):
        if start == end:
            return strs[start]
        
        mid = (start + end) // 2
        left_prefix = divide_and_conquer(start, mid)
        right_prefix = divide_and_conquer(mid + 1, end)
        
        return get_common_prefix(left_prefix, right_prefix)
    
    return divide_and_conquer(0, len(strs) - 1)

def get_common_prefix(s1, s2):
    common_prefix = ""
    for i in range(min(len(s1), len(s2))):
        if s1[i] == s2[i]:
            common_prefix += s1[i]
        else:
            break
    
    return common_prefix

4. 优化技巧:Trie树

对于大量字符串,可以使用Trie树优化搜索。Trie树将字符串的前缀存储在树中,从而可以快速查找公共前缀。

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_word = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
    
    def insert(self, word):
        current = self.root
        for c in word:
            if c not in current.children:
                current.children[c] = TrieNode()
            current = current.children[c]
        current.is_word = True
    
    def find_longest_common_prefix(self, strs):
        if not strs:
            return ""
        
        prefix = ""
        current = self.root
        for c in strs[0]:
            if c in current.children:
                prefix += c
                current = current.children[c]
            else:
                break
        
        return prefix

5. 时间复杂度和空间复杂度

  • 暴力破解法:O(n * m),其中n是字符串的数量,m是字符串的平均长度。
  • 分治法:O(n * log n)
  • Trie树:平均情况下O(n * m),最坏情况下O(n * m^2)

示例代码

strs = ["flower", "flow", "flight"]
print(find_longest_common_prefix(strs))  # 输出:"fl"
print(find_longest_common_prefix_divide_and_conquer(strs))  # 输出:"fl"
trie = Trie()
for s in strs:
    trie.insert(s)
print(trie.find_longest_common_prefix(strs))  # 输出:"fl"

结论

掌握LeetCode算法14“寻找最长公共前缀”对于任何程序员来说都是至关重要的。通过了解不同的解决方案和优化技巧,您可以有效解决此问题,并为未来的编程面试做好充分准备。欢迎在评论区分享您的经验和见解!