151. Reverse Words in a String**

151. Reverse Words in a String**

https://leetcode.com/problems/reverse-words-in-a-string/

题目描述

Given an input string, reverse the string word by word.

Example 1:

Input: "the sky is blue"
Output: "blue is sky the"

Example 2:

Input: "  hello world!  "
Output: "world! hello"
Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

Input: "a good   example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

Note:

  • A word is defined as a sequence of non-space characters.
  • Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
  • You need to reduce multiple spaces between two words to a single space in the reversed string.

Follow up:

For C programmers, try to solve it in-place in O ( 1 ) O(1) O(1) extra space.

C++ 实现 1

如果使用 stringstream 来求解, 本题非常简单. 先给出简洁的解法, 再来考虑 in-place 的使用 O ( 1 ) O(1) O(1) 空间的方法.

class Solution {
public:
    string reverseWords(string &s) {
        stringstream ss(s);
        string word;
        s = "";
        while (ss >> word) {
            s = word + " " + s;
        }
        // 上面 `word + " " + s` 这行代码会在 s 的末尾增加一个空格
        // 此处要删除该空格
        if (s != "") s = s.substr(0, s.size() - 1);
        return s;
    }
};

C++ 实现 2

(20210321 更新) C++ 实现 3 写的太复杂了, 没必要. 这题的基本思想就是先整体翻转, 然后再翻转其中的每个 word.

访问每个字符 s[i], 如果不为空格的时候, 再通过 j 来查找每个 word = s[i, ..., j) 的范围.

class Solution {
public:
    string reverseWords(string s) {
        std::reverse(s.begin(), s.end());
        string res;
        for (int i = 0; i < s.size(); ++ i) {
            if (s[i] != ' ') {
                int j = i;
                while (j < s.size() && s[j] != ' ') ++ j;
                if (!res.empty()) res += " "; // res 如果不可为空字符串, 就可以在后面加上一个空格
                auto  = s.substr(i, j - i);
                std::reverse(word.begin(), word.end());
                res += word;
                i = j;
            }
        }
        return res;
    }
};

C++ 实现 3

先依次翻转句子中的每个单词, 最后翻转整个句子. 难点在于对于空格的处理. 为了不申请额外的空间, 使用指针 k 来指示可以插入单词的位置.

class Solution {
public:
    string reverseWords(string s) {
        int k = 0;
        for (int i = 0; i < s.size(); ++ i) {
            if (s[i] == ' ') continue;
            int j = i;
            while (j < s.size() && s[j] != ' ') ++ j;
            // j 指向 s.end() 或者句子中的空格处
            if (j > i) {
                std::reverse(s.begin() + i, s.begin() + j);
                // 拷贝单词, 并增加一个空格
                while (i < j) s[k++] = s[i++];
                if (k < s.size()) s[k++] = ' ';
            }
            i = j;
        }
        // 注意此时 k 指向 s.end() 或者句子中的某处.
        // 比如对于句子 " Hello    world!", k 最后会
        // 停留在有效句子(指的去除了中间多余的空格的句子)的末尾.
        s = s.substr(0, k);
        int i = 0, j = s.size() - 1;
        // 删除多余的空格
        while (i < s.size() && s[i] == ' ') ++ i;
        while (j >= 0 && s[j] == ' ') -- j;
        s = s.substr(i, j + 1);
        std::reverse(s.begin(), s.end());
        return s;
    }
};

C++ 实现 4

更为直观的做法. 一看就懂, 但是使用了额外的空间.

class Solution {
public:
    string reverseWords(string s) {
        int k = 0;
        string res;
        for (int i = 0; i < s.size(); ++ i) {
            if (s[i] == ' ') continue;
            int j = i;
            while (j < s.size() && s[j] != ' ') ++ j;
            auto word = s.substr(i, j - i);
            std::reverse(word.begin(), word.end());
            res += word + " ";
            i = j;
        }
        if (res.back() == ' ') res = res.substr(0, res.size() - 1);
        std::reverse(res.begin(), res.end());
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值