欢迎光临
我们一直在努力

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

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

一、题目核心要求

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

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

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

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

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

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

1. 解题思路

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

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

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

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

  • 2. 代码实现(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,通过反向遍历字符串手动拼接单词,全程仅维护两个变量(结果字符串、临时单词字符串),核心逻辑:

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

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

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

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

  • 2. 代码实现(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 优化充分 略优,无正则开销
    适用场景 日常开发、快速迭代 面试、底层逻辑验证

    四、边界案例测试

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

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

  • 字符串全为空格:输入 " ",输出 "";

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

  • 字符串长度为 1:输入 "a",输出 "a",输入 " ",输出 ""。

  • 五、总结

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

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

    赞(0)
    未经允许不得转载:171主机测评 » LeetCode 151. 反转字符串中的单词:两种解法深度剖析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址