LeetCode 58简单字符串 · 扫描
最后一个单词的长度 图解题解
这道题到底在问什么
给一个字符串 s,里面是用空格隔开的单词。返回最后一个单词的长度。保证至少有一个单词,但末尾可能有多余空格。
- s
- "Hello World"
- 输出
- 5
- s
- " fly me to the moon "
- 输出
- 4(moon)
最优解:一步一步想明白
- 3想通这点是关键:答案藏在最右边。所以我们让一个指针从最后一个字符出发,一路向左。
- 4记住这两段就够了:先跳空格,再数字母,遇空格即停。下面把字符排成格子,空格用 ␣ 表示,一帧走一格看清楚。
- 5s = "a fb code "指针 cur 落在最右边第 10 格,这里是个空格 ␣。len 还是 0。先看:它是空格吗?
- 6尾部空格,visited 左移是空格!这是末尾的多余空格,不属于单词。这格封存变灰,len 不动,准备往左挪。
- 7继续看下一格cur 移到第 9 格。这里还是空格 ␣——末尾连着两个空格呢。再跳。
- 8又一个尾部空格又是空格,继续封存。两个尾部空格都跳完了,len 仍是 0。往左,看看下一格是不是真正的字母。
- 9碰到第一个字母!cur 到第 8 格,这是字母 e!跳空格阶段结束,进入数字母阶段。从这一格起,每碰到一个字母 len 就加一。
- 10第一个字母进账数它!e 标绿(算进单词),len 变 1。继续向左,看下一格还是不是字母。
- 11下一格是 dcur 移到第 7 格,是字母 d。还在单词里,接着数。
- 12第二个字母进账d 也标绿,len 变 2。绿色格子就是「最后一个单词」正在被一个个数出来。
- 13下一格是 ocur 到第 6 格,字母 o,继续数。
- 14第三个字母进账o 标绿,len 变 3。已经数出 ode 三个字母了。
- 15下一格是 ccur 到第 5 格,字母 c,还是字母,接着数。
- 16第四个字母进账c 标绿,len 变 4。单词 code 四个字母都数齐了。再往左看一格。
- 17前面是空格了cur 到第 4 格——这次是空格 ␣!这说明最后一个单词到头了。
- 18单词到头,返回 len数字母时一旦撞上空格,立刻停——前面的 fb、a 都不管了。绿色 code 就是最后一个单词,长度 4,返回!
- 19下面用 "go cat " 重走流程。一样:先跳尾部那个空格,再从右往左数字母,遇空格停。
- 20s = "go cat "新串 "go cat " 共 7 格。cur 落在第 6 格,是个空格 ␣。
- 21尾部空格封存是尾部空格,封存变灰,len 仍 0,往左。
- 22碰到字母 tcur 到第 5 格,字母 t!切到数字母阶段。
- 23第一个字母t 标绿,len = 1。
- 24字母 acur 到第 4 格,字母 a,继续数。
- 25第二个字母a 标绿,len = 2。
- 26字母 ccur 到第 3 格,字母 c,接着数。
- 27第三个字母c 标绿,len = 3。单词 cat 数齐了,再看左边一格。
- 28前面是空格cur 到第 2 格,是空格 ␣——单词到头了。
- 29返回 len = 3遇空格立刻停,前面的 go 不再管。最后一个单词 cat 长度 3,返回!两个例子的套路完全一样。
- 33"hi " 第一步就遇空格 → 0 ✗假如省掉跳空格那一步,直接在末尾数字母:第 3 格就是空格,程序立刻停、返回 0。可 "hi" 明明长 2——这就是尾部空格必须先跳的原因。
⚠️ 容易写错的地方
✗ 错:不处理尾部空格,直接从末尾数
✓ 对:先用 while 跳完尾部空格再数
"hi " 末尾两个空格,不跳的话第一步就遇空格,直接返回 0
✗ 错:从左往右找空格、切单词存数组
✓ 对:只关心最后一个词,从右往左扫一遍即可
切单词要 O(n) 额外空间,白白浪费;本题只需最后一段
完整代码(Python / C++ / Java)
Python
class Solution:
def lengthOfLastWord(self, s):
i = len(s) - 1
while i >= 0 and s[i] == ' ': # 阶段1:跳尾部空格
i -= 1
length = 0
while i >= 0 and s[i] != ' ': # 阶段2:数字母,遇空格停
length += 1
i -= 1
return lengthC++
class Solution {
public:
int lengthOfLastWord(string s) {
int i = (int)s.size() - 1;
while (i >= 0 && s[i] == ' ') i--; // 阶段1
int len = 0;
while (i >= 0 && s[i] != ' ') { len++; i--; } // 阶段2
return len;
}
};Java
class Solution {
public int lengthOfLastWord(String s) {
int i = s.length() - 1;
while (i >= 0 && s.charAt(i) == ' ') { // 阶段1
i--;
}
int len = 0;
while (i >= 0 && s.charAt(i) != ' ') { // 阶段2
len++;
i--;
}
return len;
}
}复杂度
时间复杂度
O(n)
最坏情况(整串都是一个单词)从右扫到左,每个字符最多看一次 → O(n),n 为字符串长度
空间复杂度
O(1)
只用了一个下标 i 和一个计数 len,没开额外数组/不切分单词 → 常数空间
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 最后一个单词的长度 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
为什么要先跳尾部空格?+
题目允许末尾有多余空格。若不跳,从末尾第一格就可能是空格,数字母阶段会立刻遇空格而返回 0,得到错误答案。
和 split 切单词比有什么优势?+
split 要 O(n) 额外空间存下所有单词,且扫了整串。从右往左只看最后一段,O(1) 空间、平均更快。
字符串全是空格会怎样?+
本题保证至少有一个单词,所以不会全空格;但写代码时 while 的 i>=0 边界仍要带上,防越界。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄声线把 最后一个单词的长度 一步步讲透(全站 0 节语音精讲,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。