最长公共前缀问题
问题描述
给定一个字符串数组 strs,找出其中最长的公共前缀。如果没有公共前缀,返回空字符串 ""。
示例
示例 1:
输入: strs = ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: strs = ["dog","racecar","car"]
输出: ""
解释: 没有公共前缀。
约束条件
- (1 \leq \text{strs.length} \leq 200)
- (0 \leq \text{strs[i].length} \leq 200)
strs[i]仅由小写英文字母组成。
解决方案:水平扫描法
思路
- 将第一个字符串视为初始公共前缀。
- 遍历数组中的其他字符串,不断缩短公共前缀,直到找到最长公共前缀或前缀为空。
实现代码
def longest_common_prefix(strs):
if not strs:
return ""
# 初始公共前缀为第一个字符串
prefix = strs[0]
for string in strs[1:]:
# 不断缩短 prefix,直到它是 string 的前缀
while string[:len(prefix)] != prefix and prefix:
prefix = prefix[:-1]
# 如果前缀为空,直接返回
if not prefix:
return ""
return prefix
# 测试用例
print(longest_common_prefix(["flower","flow","flight"])) # 输出: "fl"
print(longest_common_prefix(["dog","racecar","car"])) # 输出: ""
代码解析
-
初始公共前缀:
- 将数组的第一个字符串设为初始公共前缀
prefix。
- 将数组的第一个字符串设为初始公共前缀
-
逐个比较:
- 遍历剩余的字符串数组。
- 使用
string[:len(prefix)] != prefix检查当前字符串是否以prefix开头。 - 如果不是,缩短
prefix(移除最后一个字符)并继续检查。
-
终止条件:
- 如果在某次比较中,
prefix被缩短为空,则直接返回""。
- 如果在某次比较中,
-
返回结果:
- 遍历完成后,返回最终的
prefix。
- 遍历完成后,返回最终的
示例运行
输入 1:
strs = ["flower", "flow", "flight"]
运行过程:
- 初始
prefix = "flower" - 比较
"flow":"flow"[:6] != "flower",缩短为"flowe""flow"[:5] != "flowe",缩短为"flow""flow"[:4] == "flow",继续。
- 比较
"flight":"flight"[:4] != "flow",缩短为"flo""flight"[:3] != "flo",缩短为"fl""flight"[:2] == "fl",继续。
- 最终结果:
"fl"
输入 2:
strs = ["dog", "racecar", "car"]
运行过程:
- 初始
prefix = "dog" - 比较
"racecar":"racecar"[:3] != "dog",缩短为"do""racecar"[:2] != "do",缩短为"d""racecar"[:1] != "d",缩短为""
- 返回结果:
""
时间复杂度
- 最坏情况:所有字符串相同,最长公共前缀接近字符串长度。
- 比较每个字符串的每个字符:(O(S)),其中 (S = \text{所有字符串的总字符数})。
- 平均复杂度:(O(S))。
空间复杂度
- 使用常量级别的额外空间:(O(1))。
总结
这种水平扫描法通过不断缩短前缀来找到最长公共前缀,算法简单高效,适用于较小规模的字符串数组。
Leave a Reply