151. 反转字符串中的单词

63 阅读2分钟

151. 反转字符串中的单词

已解答

中等

相关标签

premium lock icon相关企业

给你一个字符串 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 <= 104
  • s 包含英文大小写字母、数字和空格 ' '
  • 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;
}