☰
笨鸟先飞:LeetCode第58题最后一个单词的长度全解析
2026/10/9 17:29:57 网站建设 项目流程

看到“先飞的笨鸟”这个标题,我第一反应是乐了:这不就是当年刚开始刷LeetCode的我吗?第58题“最后一个单词的长度”在题库里是个不起眼的简单题,难度标记为Easy,通过率长期在四成上下徘徊。但仔细琢磨会发现,这道题一点都不“简单”——它的代码量小、边界条件隐蔽、解法可以从一行写完到双指针优雅收尾,还恰好踩中了字符串处理里最典型的几个坑。对于准备面试、想要系统刷题、或者刚开始接触LeetCode的朋友来说,把它当成“笨鸟先飞”的第一站,真是再合适不过。

这道题题干很短:给定一个字符串s,由若干单词组成,单词之间用空格隔开,返回最后一个单词的长度。听起来毫无威胁,但很多人在笔试现场卡住的,恰恰不是算法,而是对边界情况的处理。比如末尾可能有多个空格、字符串可能全部是空格、单词里混着不可见字符等等。这篇文章我会把这道题的题目拆解、多种实现方案、复杂度对比、边界测试用例全部过一遍,再结合我实际刷题过程中踩过的坑,聊聊怎么用一道简单题串起LeetCode的学习路径。适合刚入门的朋友照着一行行敲,也适合正在备战面试的读者当作查漏补缺的清单。我会尽量把每一步为什么这么做讲清楚,而不是只给答案。

1. 先读懂题目:最后一个单词到底在考什么

1.1 题面拆解与“笨鸟”定位

第58题的原题描述是这样的:给你一个字符串s,由若干单词组成,单词前后用一些空格字符隔开,请返回字符串中最后一个单词的长度。单词是指仅由字母组成、不包含任何空格字符的最大子字符串。

理解这句话的关键在最后一句:“仅由字母组成、不包含任何空格字符的最大子字符串”。这意味着题目假设单词里只有字母,不会出现数字、标点符号。这个设定其实是一个隐含的简化条件,它让我们可以把注意力完全集中在“怎么找到最后一个非空格片段”这件事上。

为什么说这道题是“笨鸟先飞”的最佳起点?因为它同时具备三个特征:第一,不需要任何高深的数据结构知识,数组和字符串操作就够用;第二,解法多样,从最简单的借口函数到手动遍历都能实现,适合不同阶段的人反复练手;第三,边界条件足够多,能提前暴露很多新手在字符串处理上的通病。这三个特征组合在一起,让这道题成为一道“低门槛、高收益”的入门题。所谓先飞的笨鸟,讲的不是能力差,而是通过提前把基础打牢,用别人还在看题的时候你已经能秒掉的速度差来建立优势。

1.2 为什么第58题适合作为第一只“笨鸟”

我在各个刷题群里看到过很多人的第一题选择。有人一上来就挑战动态规划,结果被状态转移方程劝退;有人直接冲困难题,半天提交一次,心态崩得飞快。第58题作为一只“笨鸟”的起飞点,最大的价值在于它能让你在第一天就体会到“完整解题流程”带来的正反馈:读题、设计思路、写代码、跑测试、提交通过,整个过程可能只需要十五分钟。

这种正反馈对长期刷题特别重要。LeetCode上题目已经超过三千道,一天刷三道也得三年多才能刷完,没有正反馈的支撑坚持不下去。而第58题恰好能在最短时间内让你确认自己做题的方法论是否成立。另外,这道题在面试中出现频率不低,因为它可以快速考察候选人对字符串处理和边界条件的敏感度。很多公司的笔试第一题就是类似难度,用来筛选基本编码能力。把这道题练到闭着眼睛能写出来,绝对不亏。

2. 核心实现:两种解法的完整拆解

2.1 最直观的split解法

大多数人第一次看到这道题的第一反应是用split按空格把字符串切成列表,然后取最后一个元素。用Python写甚至只需要两行:

def lengthOfLastWord(s: str) -> int: words = s.split() return len(words[-1]) if words else 0

这个解法能通过,是因为Python的split方法有个特性:如果不传参数,它会按任意连续的空白字符进行分割,并且自动忽略首尾的空格。也就是说,输入字符串" fly me to the moon "会被直接切成["fly", "me", "to", "the", "moon"]。连续多个空格不会产生空字符串元素,这省去了很多麻烦。

但是我会建议你写完之后停下来想一想:这个解法的时间复杂度是O(n),可以接受;但是空间复杂度也是O(n),因为你生成了一个列表,把整个字符串的所有单词都存了下来。对于这道题来说,字符串长度通常不会太长,O(n)的空间完全够用。不过这个思路如果拿到一个长文本场景,比如分析一部小说里最后一个单词的长度,就会浪费大量内存。更何况力扣的进阶要求里虽然没有明确说空间O(1),但作为从业者,我总是习惯在写每次代码时问自己一句:能不能把这部分内存省掉?

2.2 更优雅的双指针写法

省掉内存的思路很简单:既然只需要最后一个单词的长度,那我从字符串末尾往前找就行了。从末尾开始,先跳过所有空格,然后数到下一个空格为止,这段距离就是答案。

def lengthOfLastWord(s: str) -> int: end = len(s) - 1 # 第一步:从右往左跳过末尾的空格 while end >= 0 and s[end] == ' ': end -= 1 # 此时 end 指向最后一个单词的最后一个字母 start = end # 第二步:继续向左移动,直到遇到空格或越界 while start >= 0 and s[start] != ' ': start -= 1 # 此时 start 指向最后一个单词前面的空格,或者为 -1 return end - start

逐行解释一下。第一个while循环是在做“定位”,把指针从字符串末尾往左移动,忽略掉尾部的所有空格。比如"Hello World ",循环结束后end会停在'd'上。第二个while循环是从这个位置继续往左,直到遇到空格或者指针越界为止。拿"Hello World"举例,第一个循环直接跳过,因为末尾没有空格;第二个循环中start从'd'开始往左数,走到空格前停下,此时end - start正好是5,也就是"World"的长度。

如果整个字符串全是空格,比如" ",第一个循环会让end一路减到-1,第二个循环因为start一开始就是-1,条件不成立,直接返回0。这个结果天然是正确的,因为不存在单词。如果字符串是一个单词,比如"hello",第二个循环会让start一路走到-1,此时end - start = 5 - 0 = 5,也正确,因为最后一个单词的长度就是整个字符串的长度。

这个解法的时间复杂度同样是O(n),但空间复杂度降到了O(1),只用了两个整数变量。写起来比split版本稍长一点点,但省下了整个单词列表的内存,也更贴近很多面试官期望看到的“手写遍历”风格。

2.3 边界条件与测试用例设计

写算法题最忌讳的是“上传代码前不测试”。我见过不少人在本地跑了一个用例就提交,结果因为边界条件翻车。第58题的边界条件其实非常经典,我整理了一张表,建议你对着这张表测一遍再提交。

输入预期输出说明
"Hello World"5常规情况,末尾无空格
" fly me to the moon "4首尾和中间都有多个连续空格
"luffy is still joyboy"6中间正常空格,最后一个单词较长
"hello"5只有一个单词,无空格
" "0单个空格
" "0全部是空格
"a"1单个字母
""0空字符串

注意表格里最后一行,空字符串在LeetCode的测试数据里通常不会出现,题干默认字符串至少包含一个单词。但自己在本地测试时加上这个用例没有坏处,可以验证代码在极端情况下的鲁棒性。我自己的习惯是写完代码后,先把这些用例一个个跑一遍,再点提交。这看起来多花了三十秒,实际上能避免提交两三次才通过的尴尬——提交次数多了,平台会扣分,面试里也会显得不严谨。

3. 把一道题当跳板:刷题路径与技术延伸

3.1 从58题到热门100题的选择策略

第58题刷完,下一步该做什么?很多人会直接按题号顺序往后刷,从第59题开始一路刷下去。我不推荐这条路,因为按题号刷题等于随机漫步,今天碰到螺旋矩阵,明天碰到合并区间,知识点之间没有递进关系,反而让大脑一直处于切换状态,记忆效果很差。更聪明的做法是围绕“LeetCode热门100题”这份清单来规划。

热门100题是社区里经过大量面试反馈沉淀下来的题目集合,覆盖了数组、字符串、链表、二叉树、动态规划、回溯等高频考点。第58题本身不在热门100题里,但它和热门100题中的很多字符串题共享基础技巧。例如,第125题验证回文串、第344题反转字符串,都涉及对字符串边界和字符的判断;第151题反转字符串中的单词,更是第58题的直接加强版,它要求先逆序整个字符串,再逆序每个单词,本质上就是先找到单词边界再处理。

所以我的建议是把第58题当成“摸底测试”,做完之后去热门100题里挑字符串和数组分类下的简单题,依次推进。每做一道新题,问自己三个问题:这道题用到的技巧和第58题有什么共性?有没有新的边界条件出现?我能不能用双指针的思路扩展到这道题上?带着这些问题刷题,每一道题都在帮上一道题加固记忆。

3.2 周赛430:用竞赛检验“笨鸟”成色

很多刷了一阵子题的人会把“LeetCode周赛430”这类赛事当成试金石。周赛是LeetCode每周固定举办的限时编程比赛,通常包含四道题,难度从简单到困难递增。第430场周赛我参加过,第一题往往是那种“只要手速够快就能过”的送分题,难度和第58题相仿。对于“先飞的笨鸟”来说,周赛是最好的检验场:它逼你在有限时间内读完题、写出代码、处理边界、提交通过,一整条流程下来,你会非常清楚自己在压力下的编码水平。

我第一次参加周赛时,第一题写了快四十分钟,原因不是题目难,而是紧张到忘了怎么处理输入输出的细节。后来我养成了一个习惯:每周提前把本周周赛的题目预告看一眼,如果是字符串处理相关的简单题,就先在纸上把第58题的双指针写法默写一遍。这个动作特别管用,相当于赛前热身,让手指记住“跳过空格—统计长度”的节奏。周赛成绩不理想不用太沮丧,记住一个原则:周赛不是为了拿排名,是为了暴露短板。今天暴露一个,明天就补一个,这就是笨鸟先飞的真实含义。

3.3 073爱吃香蕉的狒狒:一次必要的进阶

当你在字符串题上积累了一定手感之后,我特别推荐去做“LeetCode 073爱吃香蕉的狒狒”这道题。很多人在刷题时会有个误区,觉得简单题刷够了才能碰中等题。其实不然,有一类中等题并不要求你掌握新算法,而是把“猜答案”这件事结构化。爱吃香蕉的狒狒是一道典型的二分查找应用题,它让你在“每小时吃K根香蕉能在H小时内吃完”的条件下去寻找最小的K。

你可能会奇怪,为什么从第58题这种字符串题跳到二分查找的题?我来说说这两道题的内在联系。第58题训练的是“在一个线性结构里定位边界”,从后往前数、跳出循环的条件判断,这些基本功本质上和二分查找里的low和high指针移动是同一种心智模型。二分查找的精髓就是不断缩小搜索区间,而第58题的双指针从尾部向左收缩,也是在缩小搜索区间。会了前者,理解后者就顺理成章。

所以,第58题的意义不只是一道题,它是一个思维起点。从字符串边界的定位出发,你可以延伸到回文串判断、单词反转、子串匹配,再到二分查找这类搜索区间的经典算法。这条学习路径是有层次的,每一站都是用上一站的工具来解决新问题。我把这种“笨鸟先飞”的路径总结为:先在一个小技能点上做到滚瓜烂熟,然后用它去撬动相邻的知识点,再一步步铺开成完整知识网络。

4. 常见问题与排查技巧实录

4.1 写代码时最容易踩的坑

这道题虽然简单,但我在实际跑代码时见过不少奇怪的报错和错误输出,这里挑几个典型的说一下。

第一个坑:用split方法后不检查列表是否为空。有的新手会直接写return len(s.split()[-1]),当输入全是空格时,split之后是空列表,取[-1]会直接抛IndexError。力扣的测试用例一般不会给这样的输入,但用自己的测试用例时很容易踩中。

第二个坑:忘记去掉末尾空格的循环条件。如果只做第二个循环,而不先跳过末尾空格,比如输入是"World ",你会从最后一个字符开始数,先把空格数进去,然后遇到r停下算长度,得到结果是0而不是5。这个问题我见过很多次,而且它不像空列表那样会报错,而是静默返回错误答案,特别容易让人一头雾水。

第三个坑:索引越界。手动写双指针时,循环结束条件里如果用s[end]而忘记判断end >= 0,当字符串全是空格时,end会一路减到-1,此时再访问s[-1]会取到字符串里的最后一个字符,Python的负索引不会报错,但逻辑就完全错了。这一点在Python里尤其隐蔽,因为负索引会让你以为没出问题。

第四个坑:把!= ' '写成is not ' '。这个错误初看觉得好笑,但确实发生过。Python的字符串比较要用==或!=,is比较的是对象地址,不是内容。虽然字符串在Python里可能有驻留机制,短字符串偶尔能工作,但这是靠运气,不是正确写法。

4.2 阅读题解的正确姿势

刷题过程中,LeetCode题解区是最宝贵的资源之一,但很多人不会用。我见过两类极端:一类人完全不看题解,自己死磕一下午;另一类人每道题都先翻题解,看完就觉得自己会了。这两种方式效率都不高。

对于第58题这样的简单题,我的建议是至少自己独立写出一种解法,再来对照题解。如果一上来就看题解,你失去的是“从零到一”的思考过程,而这个过程恰恰是最有价值的训练。当你自己写完之后,再看题解里的双指针版、用语言特性一行过的版本、用正则的版本,你会发现同样一道题可以有完全不同的肌肉记忆,这会打开思路。更进阶一点的做法是总结题解里的代码风格:有的人会提前判空然后优雅处理,有的人会把主逻辑抽成小函数。这些风格会影响你在白板面试时给面试官的印象。

我在刷题早期养成的习惯是:每道题的题解用自己的话重写一遍,然后在评论区找点赞最高的一两个方案,看看它们比我强在哪。第58题的题解区里,最高赞答案经常是四行C++代码,简洁到让人叹服。这种“原来可以这么写”的冲击感,正是推动笨鸟持续先飞的内在动力。

这之后我还想多说一点:如果你在未来某天刷到第151题“反转字符串中的单词”,记得回头再看一眼第58题。第151题需要你把每个单词的顺序反过来,但第一步依然是找到单词边界。你会发现,当年那只笨鸟在简单题里反复练过的双指针技巧,正是一切复杂字符串操作的地基。这也是我一直觉得第58题值得反复咀嚼的原因——它像一块最普通的砖,但所有的墙,都是从这样的砖开始垒起来的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询