LeetCode 151. 反转字符串中的单词:两种解法深度剖析

在字符串处理类算法题中,LeetCode 151 题"反转字符串中的单词"是一道经典入门题。它不仅考察对字符串基本操作的掌握,还能延伸出"API 调用"与"手动模拟"两种核心解题思路,适合不同场景下的应用。本文将详细拆解题目要求,深入分析两种解法的原理、代码细节及优劣差异,帮助大家彻底掌握这道题。

一、题目核心要求

题目给出一个字符串 s,要求反转其中单词的顺序,同时需满足以下约束条件:

  • 单词定义:由非空格字符组成的连续字符串,单词间用至少一个空格分隔;

  • 输入特性:可能存在前导空格、尾随空格、单词间多个空格;

  • 输出要求:单词顺序颠倒,单词间仅用单个空格分隔,无任何额外空格。

示例:输入 " hello world ",输出 "world hello";输入 "a good example",输出 "example good a"

二、解法一:API 快速实现(简洁高效)

1. 解题思路

利用 JavaScript/TypeScript 内置字符串、数组 API,三步完成需求:

  1. trim():去除字符串首尾的空格,解决前导、尾随空格问题;

  2. split(/\s+/):以一个或多个空格为分隔符拆分字符串,得到无空元素的单词数组(解决单词间多空格问题);

  3. reverse().join(' '):反转单词数组,再用单个空格连接,得到最终结果。

2. 代码实现(TypeScript)

typescript 复制代码
function reverseWords_1(s: string): string {
  const sArr = s.trim().split(/\s+/);
  return sArr.reverse().join(' ');
};

3. 解法分析

优点 :代码极度简洁,开发效率高,内置 API 经过优化,在大多数场景下性能足够优秀。拆分时使用正则表达式 /\s+/ 精准匹配多空格,避免拆分后出现空数组元素,无需额外过滤。

缺点:过度依赖 API,若在面试中仅给出此解法,可能无法体现对字符串底层操作的理解;正则表达式的执行成本略高于纯循环(但在常规字符串长度下可忽略)。

时间复杂度 :O(n),其中 n 为字符串长度。trim()split()reverse()join() 均为线性时间操作。

空间复杂度:O(n),拆分后得到的单词数组需占用 O(n) 额外空间。

二、解法二:手动模拟(底层逻辑实现)

1. 解题思路

不依赖复杂 API,通过反向遍历字符串手动拼接单词,全程仅维护两个变量(结果字符串、临时单词字符串),核心逻辑:

  1. 从字符串末尾开始反向遍历,逐个读取字符;

  2. 遇到非空格字符时,拼接到临时单词字符串的头部(因反向遍历,需保证单词内部顺序正确);

  3. 遇到空格且临时单词非空时,说明已完整读取一个单词,将其拼接到结果字符串后,重置临时单词;

  4. 遍历结束后,若临时单词非空(说明第一个单词未拼接),补充到结果字符串,最后去除首尾可能存在的空格(仅尾部可能有多余空格)。

2. 代码实现(TypeScript)

typescript 复制代码
function reverseWords_2(s: string): string {
  const sL = s.length;
  let res = '';
  let word = '';
  for (let i = sL - 1; i >= 0; i--) {
    const char = s[i];
    if (char !== ' ') {
      // 非空格字符,拼接到单词头部(维持单词原顺序)
      word = char + word;
    } else if (word) {
      // 遇到空格且有已拼接单词,存入结果并重置单词
      res += word + ' ';
      word = '';
    }
  }
  // 补充最后一个单词(遍历结束时word可能非空)
  if (word) {
    res += word;
  }
  return res.trim();
};

3. 关键细节说明

  • 反向遍历的优势:无需先拆分所有单词再反转,可边遍历边构建结果,逻辑更直观;

  • 单词拼接方式:word = char + word 而非 word += char,因为反向遍历读取单词的顺序是"末尾→开头",拼接到头部才能还原单词原顺序;

  • 空格判断条件:else if (word) 避免了多个空格连续出现时重复拼接空内容,同时跳过字符串开头(反向遍历的末尾)的空格;

  • 遍历后补充单词:因字符串开头(反向遍历的末尾)无空格,最后一个单词无法通过"遇到空格"触发拼接,需单独处理。

4. 解法分析

优点:完全体现底层逻辑,适合面试场景,能展示对字符串操作的深刻理解;无正则表达式开销,空间利用率更优(可视为 O(1) 额外空间,仅用两个变量,忽略结果存储的空间)。

缺点:代码行数较多,需注意边界条件(如单个单词、全空格字符串),容易出现逻辑漏洞。

时间复杂度:O(n),仅遍历一次字符串,所有操作均为常数时间。

空间复杂度:O(n),结果字符串和临时单词字符串的总长度不超过原字符串长度。

三、两种解法对比与适用场景

维度 API 解法 手动模拟解法
代码简洁度 极高,一行核心逻辑 中等,需处理边界条件
底层理解体现 弱,依赖内置 API 强,手动实现核心逻辑
性能 优秀,API 优化充分 略优,无正则开销
适用场景 日常开发、快速迭代 面试、底层逻辑验证

四、边界案例测试

无论哪种解法,都需覆盖以下边界案例,确保正确性:

  1. 字符串仅含一个单词:输入 "hello",输出 "hello"

  2. 字符串全为空格:输入 " ",输出 ""

  3. 单词间多个空格:输入 "a b c ",输出 "c b a"

  4. 字符串长度为 1:输入 "a",输出 "a",输入 " ",输出 ""

五、总结

LeetCode 151 题的两种解法各有侧重:API 解法胜在简洁高效,适合实际开发中的快速实现;手动模拟解法胜在底层逻辑清晰,是面试中的加分项。

核心考点在于"处理空格"与"反转单词顺序",无论哪种解法,都需明确:① 如何去除多余空格;② 如何保证单词内部顺序正确;③ 如何反转单词间的顺序。掌握这两个解法,既能应对日常开发需求,也能从容应对面试中的深度提问。

相关推荐
夏幻灵35 分钟前
HTML5里最常用的十大标签
前端·html·html5
dazzle37 分钟前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵38 分钟前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
Mr Xu_1 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝1 小时前
RBAC前端架构-01:项目初始化
前端·架构
张张努力变强1 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
程序员agions1 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发1 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
张登杰踩1 小时前
MCR ALS 多元曲线分辨算法详解
算法
程序员猫哥_1 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html