LeetCode14. python实现:最长公共前缀问题☆

本文介绍了一种查找字符串数组中最长公共前缀的算法,包括暴力实现和更高效的二分查找实现,通过实例展示了不同方法的效率对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

问题

解题思路

python具体实现

1.暴力实现

 2.二分查找实现

题外话


问题

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""


示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。


解题思路

    分析

1)一种最简单的实现方法,即暴力实现:随便选择数组中的一个元素,操作简单期间,就以数组中的第一个元素来作为比较的基准;然后遍历比较该元素中的每个字符和剩余元素进行比较,一旦不符合公共前缀,立刻返回当前记录的最长公共前缀;否则遍历一遍,更新记录的最长公共前缀。

三点注意:

  1.  数组为空的情况:返回空值("")即可
  2.  数组只有一个元素的情况:则这一个元素即为最长公共前缀
  3.  数组越界的情况:因为我们是随便选取的数组中的一个元素为基准(而非数组中最短的元素为基准)。因此,循环中的停止原则,除了字符不相等外,还有数组越界情况的处理。

补充:暴力实现的一种简单改进就是选取数组中元素最短的作为基准,具体实现改进很简单,就不具体补充了!

2)二分查找实现

     基本原理同暴力实现,只是最初的比较对象,由基准元素的一个一个比较,变为基准元素的前一半进行比较,这里实现选取的基准元素改为数组中的最短元素

注意:

  1. 左指针还是右指针移动的标记的设置,即实现中的flag变量
  2. 遍历结束,mid的值就是元素minElement中最长前缀的停止位置(不包含mid所在位置)

根据上述分析,详细实现参看程序即可。


python具体实现

1.暴力实现

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        
        # 特殊情况的处理
        if len(strs)<1:    # 空数组
            return ""
        if len(strs) ==1:  # 数组只有一个元素
            return strs[0]
        
        commonStr = ""     # 存储最长公共前缀
        for i in range(len(strs[0])):
            for j in range(1,len(strs)):
                if i>len(strs[j])-1 or strs[0][i] != strs[j][i]: #两种不符合前缀的停止条件
                    return commonStr
                
            commonStr = commonStr + strs[0][i]                   # 前缀的添加
        return commonStr

 2.二分查找实现

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        # 特殊情况的处理
        if len(strs)<1:            # 空数组
            return ""
        if len(strs) ==1:          # 数组只有一个元素
            return strs[0]
        
        minElement = strs[0]
        for i in range(len(strs)): # 遍历获取数组中的最短元素
            if len(strs[i])<len(minElement):
                minElement = strs[i]
        
        # 二分查找实现部分
        left = 0
        right =len(minElement)
        mid = (left+right)//2
        while left<right:
            flag = True            # 左指针还是右指针移动 默认左指针
            for j in range(len(strs)):
                if  minElement[:mid+1] != strs[j][:mid+1]: 不符合前缀的停止条件
                    right = mid
                    flag = False
                    break
            if flag :
                left = mid+1
            mid = (left+right)//2   
            
        return minElement[:mid]   #遍历结束,mid位置就是截取的停止下一位置

题外话

    如果采用暴力实现,Take easy!一遍通过 

    对于二分查找实现,确实还是需要动下脑筋的。

   看似简单的问题,或许并不简单。参看下图的程序运行时间,二分查找实现的效率相比暴力法的效率,提高了不止三分之一,由此也可见算法的重要性!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积跬步,慕至千里

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值