news 2026/9/14 20:04:00

LeetCode 151题解析:字符串单词翻转的算法与优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 151题解析:字符串单词翻转的算法与优化

1. 每日一题3.18:编程思维训练实战

作为一名程序员,我坚持每日刷题已有五年时间。今天想和大家分享3月18日这天的精选题目解析,这是一道来自LeetCode的中等难度字符串处理问题。不同于简单的题解,我会从问题抽象、边界条件和实际工程应用三个维度展开分析。

这道题编号为151,要求翻转字符串中的单词顺序。表面看是基础操作,但隐藏着对字符串处理、空格规范和算法效率的综合考察。在真实开发场景中,类似需求常见于日志处理、文本分析和数据清洗环节。下面我将用Python和Java两种实现方式,带你从多个角度吃透这个问题。

2. 问题重述与核心难点

2.1 题目具体要求

给定一个字符串s,需要反转字符串中单词的顺序,同时:

  • 去除首尾空格
  • 将单词间多个空格缩减为单个
  • 保持单词本身的字母顺序不变

示例: 输入:" hello world " 输出:"world hello"

2.2 隐藏的考察点

这道题看似简单,但实际暗含四个关键考察维度:

  1. 字符串基础操作:包括trim、split等方法的正确使用
  2. 边界条件处理:全空格串、单单词串等特殊情况
  3. 空间复杂度优化:能否实现O(1)额外空间的原地修改
  4. 工程实践考量:如何处理Unicode字符和超大文本

3. Python实现与原理分析

3.1 基础解法(面试推荐)

def reverseWords(s: str) -> str: return ' '.join(reversed(s.split()))

这种写法虽然简洁,但需要理解其背后的处理逻辑:

  1. split()默认按任意空白字符分割,自动处理了多余空格
  2. reversed生成反转迭代器,避免创建新列表
  3. join时自动处理单词间空格

时间复杂度:O(n) 空间复杂度:O(n)

3.2 手动实现版(深入理解)

def reverseWords(s: str) -> str: words = [] word = [] for ch in s.strip(): if ch != ' ': word.append(ch) elif word: words.append(''.join(word)) word = [] if word: # 处理最后一个单词 words.append(''.join(word)) return ' '.join(reversed(words))

这个版本揭示了几个关键点:

  • strip()先处理首尾空格
  • 遇到非空格字符时累积到当前单词
  • 遇到空格时完成当前单词收集
  • 最后需要检查未处理的单词

4. Java实现与性能优化

4.1 标准库解法

public String reverseWords(String s) { s = s.trim(); List<String> wordList = Arrays.asList(s.split("\\s+")); Collections.reverse(wordList); return String.join(" ", wordList); }

注意细节:

  • trim()处理首尾空格
  • 正则表达式"\s+"匹配连续空格
  • 使用Collections.reverse进行反转

4.2 原地修改算法(进阶)

对于追求极致性能的场景,可以使用双指针实现O(1)空间复杂度:

public String reverseWords(String s) { char[] arr = s.toCharArray(); int n = arr.length; // 1. 反转整个字符串 reverse(arr, 0, n - 1); // 2. 反转每个单词 reverseWords(arr, n); // 3. 清理多余空格 return cleanSpaces(arr, n); } private void reverse(char[] arr, int i, int j) { while (i < j) { char tmp = arr[i]; arr[i++] = arr[j]; arr[j--] = tmp; } }

完整实现包含三个关键步骤,完整代码需要考虑单词边界判断和空格压缩逻辑,这种写法在内存受限环境下特别有用。

5. 边界条件与测试用例设计

5.1 必须考虑的边界情况

  1. 全空格字符串:" "
  2. 单单词字符串:"hello"
  3. 前后带空格:" test case "
  4. 连续多个空格:"a b c"
  5. Unicode字符:"你 好 世界"

5.2 测试用例示例

test_cases = [ ("the sky is blue", "blue is sky the"), (" hello world ", "world hello"), ("a good example", "example good a"), (" Bob Loves Alice ", "Alice Loves Bob"), ("", ""), ("single", "single") ]

6. 工程实践中的扩展思考

6.1 处理超长字符串

当字符串长度达到GB级别时:

  • 使用生成器逐步处理
  • 考虑内存映射文件
  • 分块处理并合并结果

6.2 多语言支持

  • 使用\w+可能无法正确匹配非ASCII单词
  • 需要根据具体语言调整单词分割逻辑
  • 考虑使用unicodedata模块检测字符类别

6.3 实际应用场景

  1. 日志分析:反转错误日志的时间序列
  2. 文本处理:准备倒排索引
  3. 数据清洗:规范化用户输入的文本

在实现这类基础算法时,我习惯先写出最直观的解法,再逐步优化。对于面试场景,建议先明确问题边界,处理完所有特殊情况后再开始编码。记得在代码中体现你对异常情况的考虑,这往往是面试官的加分点。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 20:03:14

Kafka速记:消息路径、KRaft共识与消费语义三锚点

1. 为什么“速记”不是抄概念&#xff0c;而是重建认知路径Kafka速记——这四个字在搜索框里每天被敲击上万次&#xff0c;但绝大多数人点开的所谓“速记”&#xff0c;不过是把《Kafka权威指南》第一章压缩成三页PPT&#xff0c;再配上几个加粗的名词&#xff1a;Producer、Br…

作者头像 李华
网站建设 2026/9/14 20:00:38

Starship终端优化:替代Oh My Zsh的高性能方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 20:00:31

SpringBoot+Vue体育商品推荐系统开发实战

1. 项目概述与核心价值这个基于SpringBootVueMySQL的体育商品推荐系统&#xff0c;本质上是一个融合了协同过滤算法的电商推荐平台。作为计算机专业毕业设计的经典选题&#xff0c;它完美涵盖了当前企业级应用开发的主流技术栈。我在实际开发中发现&#xff0c;这类系统最能锻炼…

作者头像 李华
网站建设 2026/9/14 20:00:25

域名投资组合构建与管理全攻略

1. 域名投资组合的概念解析域名投资组合&#xff08;Domain Portfolio&#xff09;是指个人或企业持有的多个域名的集合&#xff0c;这些域名通常具有潜在商业价值或未来升值空间。就像股票投资者会构建自己的股票组合一样&#xff0c;域名投资者也会通过系统化的方式管理自己持…

作者头像 李华