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) 中等

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


相关推荐
BirdenT1 小时前
20260519紫题训练
c++·算法
csdn_aspnet6 小时前
C语言 Lomuto分区算法(Lomuto Partition Algorithm)
c语言·开发语言·算法
谙弆悕博士7 小时前
【附C源码】从零实现C语言堆数据结构:原理、实现与应用
c语言·数据结构·算法··数据结构与算法
gaosushexiangji10 小时前
DIC系统推荐:基于千眼狼三维数字图像相关的无人机旋翼疲劳试验全场应变与位移测量
人工智能·算法
小王C语言12 小时前
【线程概念与控制】:线程封装
jvm·c++·算法
圣保罗的大教堂12 小时前
leetcode 796. 旋转字符串 简单
leetcode
kyle~12 小时前
工程数学---点云配准卡布施(Kabsch)算法(求解最优旋转矩阵)
线性代数·算法·矩阵
三品吉他手会点灯12 小时前
C语言学习笔记 - 35.数据类型 - printf函数的非输出控制符与格式优化
c语言·开发语言·笔记·学习
张二娃同学12 小时前
03_变量常量与输入输出_printf与scanf详解
算法
江南十四行13 小时前
并发编程(一)
java·jvm·算法