leetcode 每日一题 14. 最长公共前缀

1.水平扫描法

思路:

若存在最长公共前缀,即数组中每个字符串均包含公共前缀。于是可以先找出一个公共前缀,然后按顺序比较,对找到的公共前缀进行删减处理,知道最后得到最长的公共前缀。

例如:

["ababcc","ababd","abad","ac"]

①ababcc和ababd比较,得到公共前缀为abab

②abab和abad比较,得到公共前缀aba

③aba和ac比较,得到公共前缀a,所以最长的公共前缀是a

代码:

 

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        result = strs[0]
        for i in range(1,len(strs)):
            while strs[i].find(result)!=0:
                result = result[0:len(result)-1]
                if result == "":
                    return ""
        return result

 

2.垂直扫描法

思路:

从头开始,依次遍历每个字符串的字符,如果相同记录,如果不同退出。

例如:

["ababcc","ababd","abad","abd"]

ababcc   ababcc

ababd    ababd

abad      abad

abd       abd

代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        for i in range(len(strs[0])):
            for j in range(1,len(strs)):
                if i == len(strs[j]) or strs[j][i] != strs[0][i]:
                    return strs[0][0:i]
        return strs[0]

3.分治法

思路:

采用分治法,对原字符串进行拆分,两两对比找出公共前缀,同样再将对比结果两两对比,知道找到最终结果。

例如:

["ababcc","ababd","abad","abd"]

 

代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        def halfCommonPrefix(strs:List[str],left:int,right:int) ->str:
            if left == right:
                return strs[left]
            else:
                mid = (left+right)//2
                leftStr = halfCommonPrefix(strs,left,mid)
                rightStr = halfCommonPrefix(strs,mid+1,right)
                minlen = min(len(leftStr),len(rightStr))
                for i in range(minlen):
                    if leftStr[i] != rightStr[i]:
                        return leftStr[0:i]
                return leftStr[0:minlen]

        return halfCommonPrefix(strs,0,len(strs)-1)

 4.二分查找法

思路:

在使用垂直扫描法时,是通过一个个字符匹配。实际上可以先找到长度最小的那个字符串,通过二分法对其进行切分,比较前半部分,如果前半部分和数组中每个字符串都匹配,那么继续对后半部分进行二分法匹配。同理,如果前半部分不匹配,则对前半部分通过二分法切分,继续比较,直到无法二分为止。

例如:

["ababcc","ababd","abad","abbcc"]

①找到长度最小的字符串,abad

②二分法分为ab和ad

③将ab在数组中进行匹配,匹配成功,对ad进行二分,分为a和d

④发现aba不匹配,返回ab

代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        def isCommonPrefix(strs:List[str],length:int) -> bool:
            for cstr in strs:
                if not cstr.startswith(strs[0][0:length]):
                    return False
            return True
        
        minlen = len(strs[0])
        for cstr in strs:
            minlen = min(minlen,len(cstr))
        low = 0
        high = minlen
        while low <= high:
            mid = (low+high)//2
            if isCommonPrefix(strs,mid):
                low = mid+1
            else:
                high = mid-1
        return strs[0][0:(low+high)//2]

 

posted @ 2020-04-26 14:09  nil_f  阅读(206)  评论(0)    收藏  举报