问题概述
编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
解法 1:垂直扫描
工作原理
逐个位置比较所有字符串中相同位置的字符:
python
class Solution:
def longestCommonPrefix(self, strs):
if not strs:
return ""
for i in range(len(strs[0])):
char = strs[0][i]
for string in strs[1:]:
if i >= len(string) or string[i] != char:
return strs[0][:i]
return strs[0]
复杂度分析
- 时间复杂度: O(S) - 其中 S 是所有字符串中所有字符的总和
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 直观的逐字符比较
- 发现不匹配时提前终止
解法 2:水平扫描(推荐)
工作原理
从第一个字符串开始作为前缀,然后与每个后续字符串比较,根据需要缩短前缀:
python
class Solution:
def longestCommonPrefix(self, strs):
if not strs:
return ""
prefix = strs[0]
for i in range(1, len(strs)):
while not strs[i].startswith(prefix):
prefix = prefix[:-1]
if not prefix:
return ""
return prefix
关键洞察
如果所有字符串的公共前缀是 P,那么任何字符串都必须以 P 开头。我们从第一个字符串开始作为候选前缀,然后通过删除最后一个字符来缩短它,直到它与每个后续字符串的开头匹配。
复杂度分析
- 时间复杂度: O(S) - 其中 S 是所有字符串中所有字符的总和
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 推荐 - 在大多数情况下实际最快
- 简单高效
- 当前缀较短时效果很好
对比
| 方法 | 时间 | 空间 | 最佳适用 |
|---|---|---|---|
| 垂直扫描 | O(S) | O(1) | 提前终止的情况 |
| 水平扫描 | O(S) | O(1) | 大多数情况,最快 |
总结
水平扫描方法在大多数情况下实际最快。它简单、高效,在当前缀相对较短时效果很好。垂直扫描方法也很好,在某些情况下可能更早终止。