精选力扣500题 第48题 LeetCode 151. 翻转字符串里的单词c++详细题解

Posted 林深时不见鹿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精选力扣500题 第48题 LeetCode 151. 翻转字符串里的单词c++详细题解相关的知识,希望对你有一定的参考价值。

1、题目

给你一个字符串 s,逐个翻转字符串中的所有 单词

单词 是由非空格字符组成的字符串。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"
解释:如果两个单词间有多余的空格,将翻转后单词间的空格减少到只含一个。

示例 4:

输入:s = "  Bob    Loves  Alice   "
输出:"Alice Loves Bob"

示例 5:

输入:s = "Alice does not even like bob"
输出:"bob like even not does Alice"

提示:

  • 1 <= s.length <= 104
  • s包含英文大小写字母、数字和空格' '
  • s 中 至少存在一个 单词

进阶:

  • 请尝试使用O(1)额外空间复杂度的原地解法。

2、思路

(数组翻转) O ( n ) O(n) O(n)

对于样例 "the sky is blue"分两步操作:

  • 1、将字符串中的每个单词逆序,样例输入变为: "eht yks si eulb"
  • 2、将整个字符串逆序,样例输入变为:"blue is sky the"

图示样例过程:

1、将ij指针指向字符串的开头,并让j指针跳过字符串s单词的前导空格,指向单词的首非空字符。

2、再让ij指针指向同一个位置,并让j指针跳过若干个非空字符指向单词后的第一个空格。

3、将ij指针之间的单词翻转。

4、我们将翻转后的单词重新赋值给字符串s的前若干个字符(长度为单词的大小),重复上述过程。

5、最后将整个字符串翻转。

细节:

  • 赋值之后要给单词后补个空格作为单词之间的分隔符。

  • 最后要将字符串s之后多余的空格擦除。

  • 具体实现细节看代码。

时间复杂度分析: 整个字符串总共扫描两遍,所以时间复杂度是 O ( n ) O(n) O(n)。且每次翻转一个字符串时,可以用两个指针分别从两端往中间扫描,每次交换两个指针对应的字符,所以额外空间的复杂度是 O ( 1 ) O(1) O(1)

3、c++代码

class Solution {
public:
    string reverseWords(string s) {
        int k = 0;
        for(int i = 0; i < s.size(); i++)
        {
            int j = i;
            while(j < s.size() && s[j] == ' ') j++; //j指针跳过单词的前导空格
            if(j == s.size()) break; //这里break是为了保证最后不会s[k++] = ' ',多加一个空格
            i = j;
            while(j < s.size() && s[j] != ' ') j++;
            reverse(s.begin() + i, s.begin() + j);
            if(k)  s[k++] = ' '; //补个空格
            while( i < j) s[k++] = s[i++];
        }
        s.erase(s.begin() + k,s.end());//擦除多余的空格
        reverse(s.begin(),s.end());
        return s;
    }
};

原题链接: 151. 翻转字符串里的单词
在这里插入图片描述

以上是关于精选力扣500题 第48题 LeetCode 151. 翻转字符串里的单词c++详细题解的主要内容,如果未能解决你的问题,请参考以下文章

精选力扣500题 第48题 LeetCode 151. 翻转字符串里的单词c++详细题解

精选力扣500题 第13题 LeetCode 102. 二叉树的层序遍历c++详细题解

精选力扣500题 第61题 LeetCode 78. 子集c++/java详细题解

精选力扣500题 第64题 LeetCode 101. 对称二叉树c++/java详细题解

精选力扣500题 第16题 LeetCode 1. 两数之和c++详细题解

精选力扣500题 第49题 LeetCode 110. 平衡二叉树c++详细题解