Skip to content

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

 

提示:

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

     

    进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。

    方法一:双指针

    我们可以使用双指针 ij,每次找到一个单词,将其添加到结果列表中,最后将结果列表反转,再拼接成字符串即可。

    时间复杂度 O(n),空间复杂度 O(n)。其中 n 为字符串的长度。

    java
    class Solution {
        public String reverseWords(String s) {
            List<String> words = new ArrayList<>();
            int n = s.length();
            for (int i = 0; i < n;) {
                while (i < n && s.charAt(i) == ' ') {
                    ++i;
                }
                if (i < n) {
                    StringBuilder t = new StringBuilder();
                    int j = i;
                    while (j < n && s.charAt(j) != ' ') {
                        t.append(s.charAt(j++));
                    }
                    words.add(t.toString());
                    i = j;
                }
            }
            Collections.reverse(words);
            return String.join(" ", words);
        }
    }
    cpp
    class Solution {
    public:
        string reverseWords(string s) {
            int i = 0;
            int j = 0;
            int n = s.size();
            while (i < n) {
                while (i < n && s[i] == ' ') {
                    ++i;
                }
                if (i < n) {
                    if (j != 0) {
                        s[j++] = ' ';
                    }
                    int k = i;
                    while (k < n && s[k] != ' ') {
                        s[j++] = s[k++];
                    }
                    reverse(s.begin() + j - (k - i), s.begin() + j);
                    i = k;
                }
            }
            s.erase(s.begin() + j, s.end());
            reverse(s.begin(), s.end());
            return s;
        }
    };
    ts
    function reverseWords(s: string): string {
        const words: string[] = [];
        const n = s.length;
        let i = 0;
        while (i < n) {
            while (i < n && s[i] === ' ') {
                i++;
            }
            if (i < n) {
                let j = i;
                while (j < n && s[j] !== ' ') {
                    j++;
                }
                words.push(s.slice(i, j));
                i = j;
            }
        }
        return words.reverse().join(' ');
    }
    python
    class Solution:
        def reverseWords(self, s: str) -> str:
            words = []
            i, n = 0, len(s)
            while i < n:
                while i < n and s[i] == " ":
                    i += 1
                if i < n:
                    j = i
                    while j < n and s[j] != " ":
                        j += 1
                    words.append(s[i:j])
                    i = j
            return " ".join(words[::-1])

    方法二:字符串分割

    我们可以使用语言内置的字符串分割函数,将字符串按空格分割成单词列表,然后将列表反转,再拼接成字符串即可。

    时间复杂度 O(n),空间复杂度 O(n)。其中 n 为字符串的长度。

    java
    class Solution {
        public String reverseWords(String s) {
            List<String> words = Arrays.asList(s.trim().split("\\s+"));
            Collections.reverse(words);
            return String.join(" ", words);
        }
    }
    ts
    function reverseWords(s: string): string {
        return s.trim().split(/\s+/).reverse().join(' ');
    }
    python
    class Solution:
        def reverseWords(self, s: str) -> str:
            return " ".join(reversed(s.split()))

    Released under the MIT License.