已解答
中等
相关标签
相关企业
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。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 <= 104s包含英文大小写字母、数字和空格' 's中 至少存在一个 单词
进阶: 如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。
题解: 分成两步,1是删除多余空格,2是进行两次翻转。
1可以通过快慢指针原地删除。2两次翻转的reverserange函数传入字符串首地址和要翻转的范围:left和right。实现起来比较简单。
bug:
处理逐个单词翻转逻辑有一些漏洞,仅判断后面不是' '就继续往后,但是末尾'\0'也不会被识别成空格,导致一直往后读。str的末尾是有一个空字符'\0'的,牢记。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverserange(char* str, int left, int right)
{
int i, j;
char temp;
i = left;
j = right;
while (i < j)
{
temp = str[i];
str[i] = str[j];
str[j] = temp;
i ++;
j --;
}
}
int main()
{
char str[10000] = {'\0'};
int i, size = 0;
gets(str);
for (i = 0;str[i];i ++)
{
size ++;
}
//清除多余的空格
int slow = 0, fast = 0, flag = 0;
while (fast <= size - 1)
{
if (flag == 0)
{
if (str[fast] == ' ')
{
fast ++;
}
else if (str[fast] != ' ')
{
str[slow] = str[fast];
slow ++;
fast ++;
flag = 1;
}
}
else if (flag == 1)
{
if (str[fast] == ' ')
{
str[slow] = str[fast];
slow ++;
fast ++;
flag = 0;
}
else if (str[fast] != ' ')
{
str[slow] = str[fast];
slow ++;
fast ++;
}
}
}
if (str[slow - 1] == ' ')
{
str[slow - 1] = '\0';
size = slow - 1;
}
else
{
str[slow] = '\0';
size = slow;
}
//两次翻转
int left = 0, right = 0;
while (left <= size - 1)
{
if (str[right + 1] != ' ' && str[right + 1] != '\0')
{
right ++;
}
else
{
reverserange(str, left, right);
left = right + 2;
right = left;
}
}
reverserange(str, 0, size - 1);
printf("%s", str);
return 0;
}