LeetCode 14. 最长公共前缀:纵向扫描一次讲透

一、题目描述

给一组字符串,找出它们共同的开头部分。

比如:

python 复制代码
strs = ["flower", "flow", "flight"]

三个字符串都以 "fl" 开头,第 3 位开始不同,所以答案是 "fl"。

复制代码
flower
flow
flight
------
fl          ← 公共前缀

如果没有任何公共开头,返回空字符串。


二、核心思路

把所有字符串排成几行,一列一列地比。

从第 0 列开始,拿第一个字符串的字符作为标准,去和所有字符串的同一位比较:

  • 如果这一列全都相同,就把这个字符收进结果;

  • 一旦出现不同,立刻停止,返回已经收集到的结果。

    f l o w e r
    f l o w
    f l i g h t
    ↑ ↑ ↑
    0 1 2 ← 第 2 列不同,停

第 0 列都是 f,第 1 列都是 l,第 2 列出现 o 和 i 不同,停止。结果是 "fl"。


三、代码实现

python 复制代码
class Solution:
    def longestCommonPrefix(self, strs: list[str]) -> str:
        if not strs:
            return ""

        # 1. 找最短字符串长度,作为比较上限
        min_len = min(len(s) for s in strs)

        res = []
        # 2. 一列一列比
        for i in range(min_len):
            c = strs[0][i]          # 拿第一个字符串的第 i 位当标准
            for s in strs:          # 和所有字符串的第 i 位比
                if s[i] != c:
                    return "".join(res)   # 出现不同,立即返回
            res.append(c)           # 这一列全相同,收进结果

        return "".join(res)

四、逐段讲解

1. 空输入处理

python 复制代码
if not strs:
    return ""

列表为空时没有公共前缀,直接返回空字符串。

2. 找最短长度

python 复制代码
min_len = min(len(s) for s in strs)

公共前缀不可能比最短的字符串还长。比如 ["ab", "abc"],最短长度是 2,最多比到第 2 位。

这一步既是比较上限 ,也防止后面 s[i] 越界。

3. 逐列比较

python 复制代码
for i in range(min_len):
    c = strs[0][i]
    for s in strs:
        if s[i] != c:
            return "".join(res)
    res.append(c)
  • c 是这一列的"标准",取第一个字符串的第 i 位。
  • 内层 for 拿 c 去和每个字符串的第 i 位比。
  • 一旦有不同,说明公共前缀到此为止,直接返回已收集的结果。
  • 如果这一列全相同,把 c 加进 res,继续下一列。

4. 返回结果

python 复制代码
return "".join(res)

res 是字符列表,用 join 拼成字符串。


五、手动走一遍例子

以 strs = ["flower", "flow", "flight"] 为例:

轮次 i c 比较结果 res
1 0 f 都是 f ✅ ['f']
2 1 l 都是 l ✅ ['f','l']
3 2 o flight[2]='i' ❌ 返回 "fl"

第 2 列出现不同,函数提前返回 "fl"。


六、复杂度分析

  • 时间:O(n × m),n 是字符串个数,m 是最短字符串长度。最坏情况要比 m 列,每列比 n 个字符串。
  • 空间 :O(m),res 最多存 m 个字符。

七、易错点

  1. 不先求最短长度 :直接 strs[0][i] 可能越界,比如 ["ab", "abc"] 比到第 2 位就崩了。
  2. 空列表 :strs = [] 要返回 ""。
  3. 单字符串 :strs = ["abc"],公共前缀就是它自己。
  4. 空字符串 :strs = ["", "abc"],最短长度 0,循环不执行,返回 ""。
  5. flag 写法 vs 提前 return :用 flag 标记逻辑对,但用 return 提前退出更简洁。

八、原版 vs 简化版

原版(用 flag 控制):

python 复制代码
while first < l:
    c = strs[0][first]
    flag = True
    for s in strs:
        if s[first] != c:
            flag = False
            break
    if not flag:
        break
    same.append(c)
    first += 1
return "".join(same)

简化版(提前 return):

python 复制代码
for i in range(min_len):
    c = strs[0][i]
    for s in strs:
        if s[i] != c:
            return "".join(res)
    res.append(c)
return "".join(res)

两者思路完全一致。原版用 flag 控制跳出,简化版直接 return,少一层判断。


九、总结

纵向扫描的核心是一列一列比。先找最短长度确定比较上限,然后从第 0 列开始,拿第一个字符串的字符去和所有字符串的同一位比较,全都相同就收集,遇到不同就停。

优点是直观、容易理解;缺点是每次都要遍历所有字符串。

时间复杂度 O(n × m),空间复杂度 O(m)。

相关推荐
修船大队长1 小时前
CanNm 从休眠唤醒后重复消息报文的周期与数量分析
开发语言·php
事圆则缓1 小时前
Kotlin 变量与函数:把页面状态和行为写成清楚的契约
android·开发语言·kotlin
XiaoMaqqqq1 小时前
目前正规的IP驱动产业新场景新工具哪个好
网络·python·网络协议·tcp/ip
cui_ruicheng1 小时前
FastAPI 应用开发(五)——SQLAlchemy ORM、APIRouter 与 Alembic 数据库迁移
python·fastapi·web
silvamux_1 小时前
豆包 API 调用教程:Python 接入可跑通示例
开发语言·python
卿卿的产品经理日记1 小时前
【AI产品经理实战】Day 37|拆开 JSON 与 EXE:数据都有格式
人工智能·笔记·python·json·产品经理
wdfk_prog2 小时前
LWIP教程 15:IPv4 与 IPv6——从网络层工作原理到嵌入式工程取舍
运维·开发语言·网络·笔记·学习·智能路由器·ip
棉猴2 小时前
玩游戏学Python10-算术运算符应用2
开发语言·python·玩游戏·游戏编程
tachibana22 小时前
Go 语言的 Map 是否是并发安全的?
开发语言·数据结构·后端·golang·go·语言