每日一题——最长公共前缀

最长公共前缀

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

示例 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,常数个空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值