问题描述
给定一个由多个单词组成的句子,每个单词由大小写字母混合构成,单词间使用单个空格分隔。要求输出最后一个单词的长度。
约束条件:
- 每个单词非空
- 总字符长度不超过 103103
- 单词间使用单个空格分隔
示例:
1 2 3 4 |
|
解法一:从后向前遍历法(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
算法分析
时间复杂度:O(n)
最坏情况下需要遍历整个字符串
空间复杂度:O(1)
只使用了常数个额外变量
优点:
- 高效:只需要一次遍历
- 节省空间:不需要额外存储
- 鲁棒性好:能处理末尾有空格的情况
解法二:使用rfind方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
关键点说明
rfind(' '): 从字符串末尾开始查找空格string::npos: 表示未找到,值为-1(但类型为size_t,所以是最大无符号数)- 注意处理只有一个单词的情况
解法三:使用stringstream分割
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
算法特点
优点:
- 代码简洁易读
- 自动处理多余空格
- 容易扩展(如需要处理所有单词)
缺点:
- 需要额外的字符串拷贝
- 使用stringstream有额外开销
- 需要存储最后一个单词的完整副本
解法四:双指针法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
算法性能对比
| 方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 从后向前遍历 | O(n) | O(1) | 效率高,内存少 | 需要手动处理边界 |
| rfind方法 | O(n) | O(1) | 代码简洁 | 需要处理npos |
| stringstream | O(n) | O(n) | 自动处理空格 | 额外开销大 |
| 双指针法 | O(n) | O(1) | 思路清晰 | 需要两个指针 |
边界条件处理
1. 空字符串
1 2 3 4 5 |
|
2. 全是空格
1 2 3 4 5 |
|
3. 末尾有多个空格
1 2 |
|
扩展问题
1. 获取倒数第二个单词的长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
2. 统计句子中单词的数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
3. 获取最长的单词
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
实际应用场景
1. 命令行工具
1 2 |
|
2. 文本编辑器
1 2 |
|
3. 日志分析
1 |
|
4. 自然语言处理
1 2 |
|
测试用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
优化技巧
1. 使用引用避免拷贝
1 2 3 4 |
|
2. 预分配内存
1 2 |
|
3. 使用C风格字符串
1 2 3 4 5 6 7 8 9 10 11 |
|
常见错误
1. 忘记处理npos
1 2 3 |
|
2. 未考虑末尾空格
1 2 3 4 5 |
|
3. 越界访问
1 2 3 |
|
总结
获取字符串最后一个单词的长度是一个基础的字符串处理问题,但它涉及了许多重要的编程概念:
- 字符串遍历技巧:从后向前遍历是解决此类问题的关键
- 边界条件处理:空字符串、空格、单个单词等情况都需要考虑
- 算法选择:根据具体需求选择最合适的算法
- 代码鲁棒性:处理各种异常输入情况
推荐方法:从后向前遍历法
- 效率高,空间复杂度低
- 代码清晰,易于理解
- 鲁棒性好,能处理各种边界情况
掌握这个问题的解法不仅能帮助解决类似问题,还能提高字符串处理的基本功。在实际开发中,根据具体场景选择最合适的方法才是最重要的。