☰
元宝 LeetCode 151. 反转字符串中的单词 C语言实现
2026/10/5 2:30:18 网站建设 项目流程

已通过编译运行验证,输出均符合预期。下面是完整讲解。

核心思路(原地算法)

三步法,时间复杂度 O(n),额外空间 O(1)(不计返回所需):

  1. 清理空格:去掉前导、尾随空格,把中间多个连续空格压缩成单个空格
  2. 整体反转整个字符串
  3. 逐个反转每个单词

为什么这样做能对?

例:
““the sky is blue””

  • 清理后:
    ““the sky is blue””(本例无需改动)
  • 整体反转:
    ““eulb si yks eht””
  • 逐词反转:
    ““blue is sky the”” ✅

C 语言实现

// LeetCode 151. 反转字符串中的单词
#include <string.h>

/* 反转 s[left…right] */
void reverse(char *s, int left, int right) {
while (left < right) {
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right–;
}
}

char *reverseWords(char *s) {
int len = strlen(s);
int i = 0, j = 0;

// 第一步:清理空格(双指针原地压缩) while (i < len && s[i] == ' ') i++; // 跳过前导空格 while (i < len) { if (s[i] != ' ') { s[j++] = s[i++]; // 非空格字符直接拷贝 } else { // 空格:仅当结果末尾不是空格时才写入一个 if (j > 0 && s[j - 1] != ' ') { s[j++] = ' '; } i++; } } if (j > 0 && s[j - 1] == ' ') j--; // 去掉末尾可能残留的空格 s[j] = '\0'; int newLen = j; // 第二步:整体反转 reverse(s, 0, newLen - 1); // 第三步:逐个反转每个单词 int start = 0; for (int k = 0; k <= newLen; k++) { if (s[k] == ' ' || s[k] == '\0') { reverse(s, start, k - 1); start = k + 1; } } return s;

}

关键点解析

  1. 空格清理的双指针技巧

“i” 读、
“j” 写,
“j” 始终指向"已处理好的有效部分"的下一个位置。判断
“s[j-1] != ’ '” 是为了防止连续空格被写成多个。

  1. 必须处理三种多余空格

位置 例子 处理方式
前导
“” hello"" 循环开始前
“while (s[i]’ ‘) i++"
中间连续
““a b””
"if (s[j-1]!=’ ')" 才写入
尾随
""hi “” 写完后
"if (s[j-1]
’ ') j–”

  1. 边界条件
  • 空字符串
    “”“” → 返回
    “”“”
  • 全空格
    “” “” → 清理后
    “j==0”,直接返回空串
  • 单单词
    ““hello”” → 整体反转后再反转回来,结果不变
  1. C 语言特有注意
  • 参数
    “char *s” 在 LeetCode 中指向可写内存,可直接修改
  • 本地测试必须用字符数组
    “char s[] = “…”;”,不能用
    “char *s = “…”;”(字符串常量,修改会段错误)

复杂度

  • 时间:O(n),字符串遍历常数次
  • 空间:O(1),原地修改,无额外数组

完整代码与测试用例已保存,可直接编译运行验证:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询