解题思路
一、横向扫描法
根据公式lcp(s1...sn) = lcp(lcp(lcp(s1,s2),s3)...sn)
可以得知:
- 对比前两个字符串并找到公共前缀
- 将这个公共前缀与第三个字符串进行对比,再找到新的公共前缀。以此类推
代码
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs: return ""
N = len(strs)
prefix = strs[0]
for i in range(1, N):
prefix = self.lcp(prefix, strs[i])
if not prefix: break
return prefix
def lcp(self, s1, s2):
index = 0
length = min(len(s1), len(s2))
while index < length and s1[index] == s2[index]:
index += 1
return s1[:index]
二、 二分查找
这里我们换一种思路,通过二分查找来找到最长公共前缀的长度。我们知道最长公共前缀的长度是不可能大于最短字符的,记作minLength
,所以我们只需要在[0,minLength ]
中查找能缩小查找范围。
算法过程
- 创建
minLength
, 表示strs
中最短字符串的长度 - 二分查找:在
[0, minLength]
范围内进行二分查找中间值mid
,然后将mid
为截取长度与其他字符串进行匹配,直到找到最长公共字符
代码
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
def isCommonPrefix(length):
str0 = strs[0][:length]
return all(strs[i][:length] == str0 for i in range(1, len(strs)))
if not strs: return ""
minLength = min(len(s) for s in strs)
low, high = 0, minLength
while low < high:
mid = low + ((high - low + 1) >> 1)
if isCommonPrefix(mid):
low = mid
else: high = mid - 1
return strs[0][:low]