leetcode第14题,寻找一组字符串的最长公共前缀。
这道题看起来不是特别难,可以用最直接的思路解,那就是逐个遍历,垂直比较所有字符串的同一位置的字符,一旦发现不同了,就立刻终止搜索。但是我写的有点过于麻烦了。
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
strNum = len(strs)
if strNum == 0:
return ""
minlen = min([len(sstr) for sstr in strs])
if minlen == 0:
return ""
prefix = []
flag = False
for i in range(minlen):
for j in range(strNum):
if j == 0:
flag = True
ch = strs[j][i]
else:
if strs[j][i] == ch:
flag = True
else:
flag = False
break
if flag == True:
prefix.append(ch)
else:
break
return "".join(prefix)
网上思路1:水平搜索,把任意一个字符串当做公共前缀,去其他字符串中匹配,如果不成功,就缩短公共前缀的长度继续匹配,知道能匹配上所有的字符串即可,如果都匹配不了,说明没有公共前缀。这个做法代码里会减少很多,而且很清晰易懂。
def longestCommonPrefix2(self, strs):
n = len(strs)
if n == 0:
return ""
prefix = strs[0] # 取第一个字符串作为搜索基础
for i in range(1, n):
while strs[i].find(prefix) != 0: # 寻找子串,位置不是从0开始或者没找大返回了-1
prefix = strs[0][0:len(prefix)-1]
if len(prefix) == 0: # 找到最好没有公共前缀
return ""
return prefix
网上思路2:分治法,这个问题麻烦在于有很多个这样的字符串,每次都要多次比较才能看出所有字符串的同一位置上是不是相同。如果换成两个字符串比较,那就简单多了。基于这个思路,可以采用分治法,每次比较两个字符串,然后结果向上返回,一直比较到最后即可得出答案。
def commonPrefix(self,strLeft, strRight): # 寻找两个字符串的公共前缀
minLen = min(len(strLeft), len(strRight))
for i in range(minLen):
if strLeft[i] != strRight[i]:
return strLeft[:i]
return strLeft[:minLen]
def findPrefix(self, strs, left, right): # 分治法求公共前缀
if left == right:
return strs[left]
else:
mid = (left+right)/2
lcpleft = self.findPrefix(strs, left, mid)
lcpright = self.findPrefix(strs, mid+1, right)
return self.commonPrefix(lcpleft, lcpright)
def longestCommonPrefix3(self, strs):
n = len(strs)
if n == 0:
return ""
return self.findPrefix(strs, 0, n-1)