(python刷题)leetcode 第14题:最长公共前缀

题目在leetcode上的链接为:
https://leetcode-cn.com/problems/longest-common-prefix/

题目描述
在这里插入图片描述
解题思路
解法一:
暴力法。首先找到数组中字符串的最短长度,那么依次从前往后比较数组中的字符串的字符是否相同,遇到不同的字符时结束查找,即可找到最长前缀。
ps:特别注意当数组长度为0时,返回 “”;当数组长度为1时,直接返回第一个字符串

复杂度分析:
设数组中字符串的最短长度为 k,数组长度为 m,最长前缀长度为 j,那么时间复杂度为 o ( k ∗ m ∗ j ) o(k*m*j) o(kmj),这也是最坏的情况。
由于只需要常数级空间,空间复杂度为 o(1)

python代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        if len(strs) == 1:
            return strs[0]
        minLen = len(strs[0])
        for i in range(len(strs)):
            if len(strs[i]) < minLen:
                minLen = len(strs[i])
        res = ""
        i = 0
        while i < minLen:
            flag = True
            for j in range(len(strs) - 1):
                if strs[j][i] != strs[j + 1][i]:
                    flag = False
                    break
            if flag == True:
                res += strs[j][i]
                i += 1
            else:
                break
        return res

解法二:
水平扫描法。我们设 LCP(S1,S2,…,Si) 表示 S1,…,Si 的最长公共前缀,那么很容易发现 LCP((LCP(S1,S2,…,Si),Si+1) 即表示 S1,…,Si,Si+1 的最长公共前缀,也就是说我们要求数组中字符串 [S1,S2,…,Sn] 的最长公共前缀,转化为求
LCP(LCP(LCP(S1,S2),S3),…,Sn),即每迭代一次求出从一开始到当前元素的最长公共前缀,若当前最长公共前缀为"",则结束迭代,最多迭代 n 次后可得到 n 个字符串的最长公共前缀。

复杂度分析:
设 s 表示数组中所有字符串的字符数量总和,那么时间复杂度为 o(s),最坏的情况是当所有字符串多相同时,设字符串长度为 n,数组长度为 m,这时时间复杂度为 o(m*n)=o(s)
由于只需要常数级空间,空间复杂度为 o(1)

python代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ""
        if len(strs) == 1:
            return strs[0]
        prefix = strs[0]
        for i in range(1, len(strs)):
            prefix = self.longestCommonPrefixOfTwoStr(prefix, strs[i])
        return prefix
        
    def longestCommonPrefixOfTwoStr(self, str1: str, str2: str) -> str:
        res = ""
        minLen = min(len(str1), len(str2))
        i = 0
        while i < minLen:
            if str1[i] == str2[i]:
                res += str1[i]
                i += 1
            else:
                break
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值