最长公共前缀
题目描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:所有输入只包含小写字母 a-z 。
题目链接:https://leetcode-cn.com/problems/longest-common-prefix
方法一:水平扫描
思路:
对列表从头到尾进行扫描,每扫描一个元素计算公共前缀,然后让公共前缀去和后面的元素再计算公共前缀,以此类推直到最后一个元素。
具体过程如下图所示。
代码:
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if strs == []:
return ''
s = strs[0]
for ss in strs[1:]:
for i in range(len(s)):
if len(ss) < i+1:
s = ss[0:i]
continue
if s[0:i+1] == ss[0:i+1]:
continue
else:
s = s[0:i]
break
return s
时间复杂度:
假设列表长度n,每个元素长度m
O(S),S=n*m,也就是时间复杂度为整个列表的总字母个数。
空间复杂度:
O(1),我们只需要常数的空间,因为s=strs[0]存储的只是strs[0]的地址。
方法二、分而治之
思路:
将问题拆分为左右两部分的公共前缀再取公共前缀,迭代拆分致计算到每一个列表元素。
具体过程如下图:
代码:
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if strs == []:
return ''
return longestCommonPreLR(strs,0,len(strs)-1)
def longestCommonPreLR(strs,l,r):
if l == r:
return strs[l]
else:
mid = (l+r)/2
lcpLeft = longestCommonPreLR(strs,l,mid)
lcpRight = longestCommonPreLR(strs,mid+1,r)
return commonPrefix(lcpLeft,lcpRight)
def commonPrefix(left,right):
lengh = min(len(left),len(right))
if lengh == 0:
return ''
for i in range(1,lengh+1):
if left[0:i] == right[0:i]:
if i == lengh:
return left[0:i]
continue
return left[0:i-1]
时间复杂度:
O(S),S=m*n,strs的总字符个数。
空间复杂度:
待更新
方法三:二分查找
思路:
这是我拿到这道题的第一想法,首先找出长度最小的字符串,然后对该串进行二分,将分开的左边部分遍历所有字符串看是不是公共前缀,如果是,mid再向后移一半,反之mid向前移一半,一直到找到最长子串为止。
具体路上如下图所示:
代码:
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if strs == []:
return ''
min_length = min(len(s) for s in strs)
if min_length == 0:
return ''
if len(strs) == 1:
return strs[0]
start = 0
end = min_length-1
mid = (start+end)/2
while start <= end:
for j in range(len(strs)-1):
if strs[j][0:mid+1] == strs[j+1][0:mid+1]:
if j == len(strs)-2:
start = mid+1
if start > end:
return strs[0][0:mid+1]
mid = (start+end)/2
continue
end = mid-1
if start > end:
return strs[0][0:mid]
mid = (start+end)/2
break
时间复杂度:
O(Slog(n)),一共要迭代log(n)次,每次需要遍历S=mn个字符,所以时间复杂度是O(S*log(n))。
空间复杂度:
O(l),我们只需要存储min_length、start、mid、end,常数个空间。