精选力扣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. 翻转字符串里的单词
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小鹿@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值