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

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


相关推荐
智碳能碳管理平台6 小时前
工业能耗台账标准化:能碳管理系统的数据口径怎么设计
算法·能碳管理系统·智碳能碳管理平台·企业能碳管理系统·碳排放核算软件·绿色工厂申报saas·能碳管理平台
带多刺的玫瑰6 小时前
Leecode#15刷题之三数之和
算法·leetcode·职场和发展
圣保罗的大教堂7 小时前
leetcode 877. 石子游戏 中等
leetcode
羚尔7 小时前
C语言数组
c语言·开发语言
哭泣方源炼蛊7 小时前
并查集进阶 P1(带权并查集,并查集分类)
数据结构·c++·算法·二进制·带权并查集
牧羊人.3337 小时前
动手学深度学习 02 | 手写数字识别
图像处理·人工智能·深度学习·算法
武帝为此7 小时前
【InnoDB存储引擎介绍】
数据库·算法
shehuiyuelaiyuehao8 小时前
算法32,连续数组,前缀和+哈希表
算法·leetcode·职场和发展
五_谷_丰_登8 小时前
平衡二叉树(AVL)讲解二
数据结构·c++
程序员贺加贝8 小时前
报表大 IN 优化:一条 product_profile 超大 IN SQL 背后的报表任务治理
算法·性能优化