力扣 151. 反转字符串中的单词

一、题目描述

给你一个字符串 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"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

二、题解

首先通过快慢指针将字符串中的所有多余的空格去除(类似于删除字符串中指定字符),去除空格后逆置整个句子再依次逆置每个单词,时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    string reverseWords(string s) {
        /* 通过快慢双指针去除多余空格 */
        int fast = 0, slow = 0;
        /* 去除前导空格 */
        while (s.at(fast) == 32) {
            fast++;
        }
        /* 去除中间的多余空格 */
        while (fast < s.size()) {
            while (fast < s.size() - 1 && s.at(fast) == 32 && s.at(fast + 1) == 32) {
                fast++;
            }
            s.at(slow++) = s.at(fast++);
        }
        /* 去除尾随空格 */
        if (s.at(slow - 1) == 32) {
            s.resize(slow - 1);
        } else {
            s.resize(slow);
        }

        /* 逆置整个句子,然后逆置每个单词 */
        reverse(s.begin(), s.end());
        int begin = 0, end = 0;
        while (end < s.size()) {
            if (end + 1 == s.size() || s.at(end + 1) == 32) {
                reverseSingleWord(s, begin, end);
                begin = end + 2;
                end = begin;
            } else {
                end++;
            }
        }

        return s;
    }

private:
    void reverseSingleWord(string &s, int begin, int end) {
        for (int i = begin, j = end; i < j; i++, j--) {
            char tmp = s.at(i);
            s.at(i) = s.at(j);
            s.at(j) = tmp;
        }
    }
};

在这里插入图片描述

你可能感兴趣的:(数据结构与算法,leetcode,算法,职场和发展)