LeetCode【0014】最长公共前缀

news2024/11/14 2:38:18

本文目录

  • 1 中文题目
  • 2 求解思路
    • 2.1 基础解法:排序法
    • 2.2 优化解法:滑动窗口法
    • 2.3 最优解法:基于python内置函数的横向扫描法
  • 3 题目总结

1 中文题目

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

示例 :

输入:strs = ["flower","flow","flight"]
输出:"fl"
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1 ≤ s t r s . l e n g t h ≤ 200 1 \leq strs.length \leq 200 1strs.length200
  • 0 ≤ s t r s [ i ] . l e n g t h ≤ 200 0 \leq strs[i].length \leq 200 0strs[i].length200
  • s t r s [ i ] strs[i] strs[i] 仅由小写英文字母组成

2 求解思路

2.1 基础解法:排序法

思路

先对字符串数组进行字典序排序,然后只需要比较首尾两个字符串的公共前缀即可。因为字典序排序后,第一个和最后一个字符串的差异最大,它们的公共前缀一定是整个数组的公共前缀。

# 原始数组:["flower", "flow", "flight", "flake"]
sorted_strs = sorted(strs)
# 排序后:["flake", "flight", "flow", "flower"]

# 获取首尾字符串
first = "flake"
last = "flower"

Python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        使用排序法查找字符串数组中的最长公共前缀
        
        思路:
        1. 对字符串数组进行字典序排序
        2. 只需比较首尾两个字符串
        3. 找出它们的公共前缀即为结果
        
        参数:
            strs: 字符串数组,如 ["flower","flow","flight"]
        返回:
            最长公共前缀字符串,如 "fl"
        """
        # 处理特殊情况
        if not strs:
            return ""
        if len(strs) == 1:
            return strs[0]
        
        # 对字符串数组进行字典序排序
        # 排序后,第一个和最后一个字符串的差异最大
        sorted_strs = sorted(strs)
        
        # 获取首尾字符串
        first = sorted_strs[0]
        last = sorted_strs[-1]
        
        # 获取首尾字符串的最短长度
        min_length = min(len(first), len(last))
        
        # 查找公共前缀
        result = []
        for i in range(min_length):
            # 如果字符不同,直接返回当前累积的前缀
            if first[i] != last[i]:
                break
            result.append(first[i])
        
        # 返回找到的最长公共前缀
        return ''.join(result)

时空复杂度分析

  • 时间复杂度分析:O(nlogn + m)
    • 排序:O(nlogn),n为字符串数量
    • 比较:O(m),m为最短字符串长度
  • 空间复杂度分析:O(n + m)
    • 排序空间:O(n)
    • 结果空间:O(m)

2.2 优化解法:滑动窗口法

思路
从第一个字符开始,逐步扩展窗口大小,每次检查所有字符串在当前位置是否具有相同的字符。一旦发现不同字符,立即停止扩展并返回当前的公共前缀。

python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        滑动窗口法:使用逐步扩展窗口的方式
        """
        # 处理特殊情况
        if not strs:
            return ""
            
        # 初始化窗口大小为1
        prefix = ""
        min_length = min(len(s) for s in strs)
        
        # 逐步扩展窗口
        for i in range(min_length):
            current_char = strs[0][i]
            # 检查所有字符串在当前位置的字符是否相同
            if all(s[i] == current_char for s in strs):
                prefix += current_char
            else:
                break
                
        return prefix

时空复杂度分析

  • 时间复杂度分析:
    • 最好情况:O(n),n为最短字符串长度
    • 最坏情况:O(S),S为所有字符的总和
    • 平均情况:O(n×m),m为字符串个数
  • 空间复杂度分析:O(1)

2.3 最优解法:基于python内置函数的横向扫描法

思路
使用zip函数将所有字符串按位置压缩,然后逐位比较每个位置上的字符是否相同。当发现不同字符时,即可确定最长公共前缀的长度。

详细步骤解析:

  • zip函数的工作原理:
    • zip(*strs)将所有字符串解包,按位置将字符组合成元组
例如:["abc", "abd", "abf"] 转换为:
('a','a','a') # 第一位
('b','b','b') # 第二位
('c','d','f') # 第三位
  • enumerate的使用:
    • 提供当前处理的位置索引,同时获取当前位置的字符元组。i表示位置,chars表示该位置的所有字符
  • set去重判断:
    • set(chars)将字符元组转为集合,相同字符的集合长度为1,不同字符的集合长度大于1
  • 结果处理:
    • 发现不同时返回前i个字符,全部相同时返回最短字符串

示例

# 输入:strs = ["flower","flow","flight"]
# zip(*strs) 生成:
# 第1轮:('f','f','f')   # set长度为1,继续
# 第2轮:('l','l','l')   # set长度为1,继续
# 第3轮:('o','o','i')   # set长度为2,返回"fl"

python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        使用zip函数实现 
        
        参数:
            strs: 字符串数组
        返回:
            最长公共前缀字符串
        """
        # 处理特殊情况
        if not strs:
            return ""
            
        # 使用zip函数将所有字符串按位置打包
        for i, chars in enumerate(zip(*strs)):
            # 检查当前位置的所有字符是否相同
            if len(set(chars)) != 1:
                # 不相同时返回之前的前缀
                return strs[0][:i]
        
        # 所有字符都相同,返回最短字符串
        return min(strs, key=len)

时空复杂度分析

  • 时间复杂度分析:O(S):S是所有字符串的字符数总和
    • zip操作需要遍历所有字符
    • set操作为O(1)
    • min操作为O(n),n为字符串个数
  • 空间复杂度分析:O(1)

3 题目总结

题目难度:简单
数据结构:字符串数组
应用算法:python内置函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刘铁猛C#入门 024 类的声明,继承和访问控制

类声明的全貌 C#声明类的位置 声明既定义(C#与Java) 类的修饰符 最简单的类声明 类的访间控制 :默认internal 共性 public 和 internal 都是访问修饰符,用于定义一个类型的成员可以被谁访问。它们都可以用来声明类、结构、接口、枚举、字段、方法、…

人工智能(AI)对于电商行业的变革和意义

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/402a907e12694df5a34f8f266385f3d2.png#pic_center> 🎓作者简介:全栈领域优质创作者 🌐个人主页:百锦再新空间代码工作室 📞工作室:新空间代…

pgsql 版本升级和数据迁移(编译版)

最近给pgsql从16.0升级到16.4,有挺多细节 1.关闭pgsql 为了保证数据一致性和过渡平稳,还是需要暂停pgsql。 systemctl stop pgsql2.备份现有数据 需要切换到pgsql的用户,通常用root是不行的 pg_dumpall > /xxx/xxx/backup.sql3.重命名…

⚙️ 如何调整重试策略以适应不同的业务需求?

调整 Kafka 生产者和消费者的重试策略以适应不同的业务需求,需要根据业务的特性和容错要求来进行细致的配置。以下是一些关键的调整策略: 业务重要性: 对于关键业务消息,可以增加重试次数,并设置较长的重试间隔&#x…

uniCloud云对象调用第三方接口,根据IP获取用户归属地的免费API接口,亲测可用

需求 在2022年5月初,网络上各大平台上,都开始展示用户IP属地,在某音、某手等小视频平台以及各主流网站应用中,都展示IP归属地,如下图所示: 解决办法 收费文档的肯定有很多,基本你百度搜“归…

蓝桥杯PythonB组扫盲

题目分布(参考2024年省赛):总共八道题,两填空8代码(考察计算机基础知识和一些简单数学计算知识,不会太难,稍微准备下就行),六道程序设计题(重点和难点&#x…

STM32单片机WIFI语音识别智能衣柜除湿消毒照明

实践制作DIY- GC0196-WIFI语音识别智能衣柜 一、功能说明: 基于STM32单片机设计-WIFI语音识别智能衣柜 二、功能介绍: STM32F103C系列最小系统板LCD1602显示器ULN2003控制的步进电机(柜门开关)5V加热片直流风扇紫外消毒灯DHT11…

git重置的四种类型(Git Reset)

git区域概念 1.工作区:IDEA中红色显示文件为工作区中的文件 (还未使用git add命令加入暂存区) 2.暂存区:IDEA中绿色(本次还未提交的新增的文件显示为绿色)或者蓝色(本次修改的之前版本提交的文件但本次还未提交的文件显示为蓝色)显示的文件为暂存区中的文件(使用了…

MySQL技巧之跨服务器数据查询:基础篇-更新语句如何写

MySQL技巧之跨服务器数据查询:基础篇-更新语句如何写 上一篇已经描述:借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQL 以及用同样的…

C#入门 023 什么是类(Class)

什么是“类” 是一种数据结构 是一种数据类型 代表现实世界中的“种类” 构造器和析构器 析构器 析构器(Destructor)是一种特殊的成员方法,用于在对象被垃圾回收器(Garbage Collector, GC)回收之前执行清理操作。…

AXI DMA (一)

免责声明:本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下,作者不对因使用本文内容而导致的任何直接或间接损失承担责任,包括但不限于数据丢失、业务中断或其他经济…

ubuntu 安装kafka-eagle

上传压缩包 kafka-eagle-bin-2.0.8.tar.gz 到集群 /root/efak 目录 cd /root/efak tar -zxvf kafka-eagle-bin-2.0.8.tar.gz cd /root/efak/kafka-eagle-bin-2.0.8 mkdir /root/efakmodule tar -zxvf efak-web-2.0.8-bin.tar.gz -C /root/efakmodule/ mv /root/efakmodule/efak…

TCP 三次握手意义及为什么是三次握手

✨✨✨励志成为超级技术宅 ✨✨✨ TCP的三次握手在笔试和面试中经常考察,非常重要,那么大家有没有思考过为什么是三次握手,俩次握手行不行呢?四次握手行不行呢?如果大家有疑问或者不是很理解,那么这篇博客…

vmware在全屏模式下快速切换回win桌面的方法

window上开发没有ubuntu下的方便,经常在window主机和ubuntu虚拟机直接切换太麻烦,每次得ctrlalt从虚拟机释放鼠标才可以切换,经过折腾发现以下几种方法可行 方法1 虚拟机监听切换按键并通知主机进行切换桌面 虚拟主机放在单独的一个桌面上并…

[Docker#8] 容器配置 | Mysql | Redis | C++ | 资源控制 | 命令对比

目录 一:Mysql 容器化安装 二:Redis 容器化安装 Redis 简介 Redis 容器创建 三:C容器制作 四:容器资源更新 常见问题 一:Mysql 容器化安装 进入 mysql 的镜像网站,查找 mysql 的镜像 mysql docker…

泷羽sec学习打卡-Linux基础

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于Linux的那些事儿-Base 一、Linux-Base什么时openssl?有哪些加密参数?常用lin…

SpringBoot后端解决跨域问题

1.全局方式 新建一个conifg配置类,内容如下: Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//是否发送Cookie.allowCrede…

odoo17 owl 前端 顶部导航栏右侧添加自定义按钮

odoo17 前端 顶部导航栏右侧添加自定义按钮 先看图 很多时候都想要在这添加个自定义按钮或图标, 无穷下手添加 这里将展示如何在顶部header添加自定义 添加自定义模块 demo 目录结构如下 └─demo│ __init__.py│ __manifest__.py│├─static│ └─src│ ├─s…

Power bi中的lookupvalue函数

lookupvalue函数是一个非常实用的函数,它可用于在两个表之间查找相应的值。kagkupMalue函数可以将一个表中的列值作为参数传递给另一个表中的列,并返回在第二个表中与该值匹配的另一个列的值。在实践中,lookupvalue函数通常用于两个表之间的关…

golang分布式缓存项目 Day5 分布式节点

该项目原作者:https://geektutu.com/post/geecache-day1.html。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习 1 流程回顾注: 我们在GeeCache 第二天 中描述了 geecache 的流程。在这之前已经实现了流程 ⑴ 和 ⑶&#xf…