LeetCode 151. 反转字符串中的单词(C语言)【双指针 + 字符串处理】

一、题目描述

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

  • 单词是由 非空格字符组成的字符串

  • s 中使用至少一个空格将字符串中的单词分隔开。

  • 返回 单词顺序颠倒且单词之间用单个空格连接 的结果字符串。

需要注意:

  • 输入字符串可能包含 前导空格

  • 可能包含 尾随空格

  • 单词之间可能有 多个空格

  • 结果字符串 不能包含多余空格

示例 1

复制代码
输入:s = "the sky is blue"
输出:"blue is sky the"

示例 2

复制代码
输入:s = "  hello world  "
输出:"world hello"

示例 3

复制代码
输入:s = "a good   example"
输出:"example good a"

提示

复制代码
1 <= s.length <= 10^4
s 由英文字母、数字和空格组成
s 中至少存在一个单词

二、解题思路

题目的核心要求有三个:

  1. 去除多余空格

  2. 提取每个单词

  3. 反转单词顺序

我们可以采用 字符串扫描 + 倒序拼接 的方式完成。

整体步骤如下:

1 跳过多余空格

遍历字符串时:

  • 先跳过所有 ' ' 空格

  • 找到单词开始位置

例如:

复制代码
"   hello world  "
    ^

跳过空格后指向 hello


2 提取单词

继续向后遍历直到遇到空格:

复制代码
hello
^   ^
start end

这样我们就得到了一个单词。

然后把这个单词保存起来。


3 保存所有单词

依次扫描字符串,把所有单词存入数组:

复制代码
["the", "sky", "is", "blue"]

4 倒序拼接

将数组 从后向前拼接

复制代码
blue is sky the

拼接时:

  • 单词之间加入一个空格

  • 最后一个单词后不加空格


三、代码实现(C语言)

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* reverseWords(char* s) {
    int len = strlen(s);
    
    // 存储单词指针
    char** words = (char**)malloc(sizeof(char*) * len);
    int wordCount = 0;

    int i = 0;

    while (i < len) {

        // 1 跳过空格
        while (i < len && s[i] == ' ')
            i++;

        if (i >= len)
            break;

        int start = i;

        // 2 找到单词结尾
        while (i < len && s[i] != ' ')
            i++;

        int end = i;

        // 3 提取单词
        int wordLen = end - start;
        char* word = (char*)malloc(wordLen + 1);

        strncpy(word, s + start, wordLen);
        word[wordLen] = '\0';

        words[wordCount++] = word;
    }

    // 4 计算结果长度
    int totalLen = 0;
    for (i = 0; i < wordCount; i++)
        totalLen += strlen(words[i]);

    totalLen += wordCount - 1;

    char* result = (char*)malloc(totalLen + 1);
    result[0] = '\0';

    // 5 倒序拼接
    for (i = wordCount - 1; i >= 0; i--) {
        strcat(result, words[i]);

        if (i > 0)
            strcat(result, " ");

        free(words[i]);
    }

    free(words);

    return result;
}

四、复杂度分析

时间复杂度

复制代码
O(n)
  • 遍历字符串一次

  • 拼接字符串一次

整体仍然是线性复杂度。


空间复杂度

复制代码
O(n)

需要额外数组存储单词。


五、进一步优化(进阶)

题目进阶要求 O(1) 额外空间,可以采用经典三步:

  1. 去除多余空格

  2. 整体反转字符串

  3. 逐个单词再反转

例如:

复制代码
原字符串
the sky is blue

整体反转
eulb si yks eht

逐词反转
blue is sky the

这样可以做到 原地修改字符串


六、总结

本题是一道非常经典的 字符串处理题,重点在于:

  • 跳过多余空格

  • 正确识别单词边界

  • 控制结果字符串的空格数量

常见做法有两种:

方法 空间复杂度 难度
提取单词 + 倒序拼接 O(n) 简单
原地三次反转 O(1) 中等

在面试中,建议优先写 提取单词版本,代码清晰不容易出错。


相关推荐
Forever Nore16 分钟前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考2 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX3 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面3 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号3 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽4 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI4 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
C++ 老炮儿的技术栈5 小时前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
MC皮蛋侠客5 小时前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis
疯狂打码的少年5 小时前
【数据结构】队列:定义、顺序队列与链式队列
数据结构·笔记