557. (Reverse Words in a String III)反转字符串中的单词 III

给定字符串s,反转每个单词的字符顺序,同时保持空格和初始单词顺序。例如输入"Let's take LeetCode contest",输出"s'teL ekat edoCteeL tsetnoc"。解题方法包括使用额外空间和原地解法,分别具有不同的时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

题目:

Given a string s, reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

给定一个字符串s,将句子中每个单词的字符顺序颠倒,同时仍然保留空格和最初的单词顺序。

Example 1:

Input: s = “Let’s take LeetCode contest”
Output: “s’teL ekat edoCteeL tsetnoc”

示例1:

输入:“Let’s take LeetCode contest”
输出:“s’teL ekat edoCteeL tsetnoc”

Example 2:

Input: s = “God Ding”
Output: “doG gniD”

示例2:

输入: “God Ding”
输出:“doG gniD”

Constraints:

  • 1 <= s.length <= 5 * 1 0 4 10^4 104
  • s contains printable ASCII characters.
  • s does not contain any leading or trailing spaces.
  • There is at least one word in s.
  • All the words in s are separated by a single space.

提示:

  • 1 <= s.length <= 5 * 1 0 4 10^4 104
  • s包含可打印的ASCII字符。
  • s不包含任何前导或尾随空格。
  • s中至少有一个单词。
  • “s”中的所有单词之间用一个空格隔开。

解题思路:

方法一:使用额外空间

开辟一个新字符串。然后从头到尾遍历原字符串,直到找到空格为止,此时找到了一个单词,并能得到单词的起止位置。随后,根据单词的起止位置,可以将该单词逆序放到新字符串当中。如此循环多次,直到遍历完原字符串,就能得到翻转后的结果

C++代码

class Solution {
public:
    string reverseWords(string s) {
        string res;
        int n = s.size();
        int i = 0;
        while (i < n) {
            int start = i;
            while (i < n && s[i] != ' ') {
                i++;
            }
            for (int p = start; p < i; p++) {
                res.push_back(s[start + i - 1 - p]);
            }
            while (i < n && s[i] == ' ') {
                i++;
                res.push_back(' ');
            }
        }
        return res;
    }
};

Java代码

class Solution {
    public String reverseWords(String s) {
        StringBuffer res = new StringBuffer();
        int n = s.length();
        int i = 0;
        while (i < n) {
            int start = i;
            while (i < n && s.charAt(i) != ' ') {
                i++;
            }
            for (int p = start; p < i; p++) {
                res.append(s.charAt(start + i - 1 - p));
            }
            while (i < n && s.charAt(i) == ' ') {
                i++;
                res.append(' ');
            }
        }
        return res.toString();
    }
}

复杂度分析

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

方法二:原地解法

此题也是方法一的升级版,避免额外的空间开销。当找到一个单词的时候,我们交换字符串第一个字符与倒数第一个字符,随后交换第二个字符与倒数第二个字符……如此反复,就可以在原空间上翻转单词。

注意:

原地解法在某些语言(比如 Java,JavaScript)中不适用,因为在这些语言中 String 类型是一个不可变的类型。

C++代码

class Solution {
public: 
    string reverseWords(string s) {
        int= s.size();
        int i = 0;
        while (i <) {
            int start = i;
            while (i <&& s[i] != ' ') {
                i++;
            }

            int left = start, right = i - 1;
            while (left < right) {
                swap(s[left], s[right]);
                left++;
                right--;
            }
            while (i <&& s[i] == ' ') {
                i++;
            }
        }
        return s;
    }
};

复杂度分析:

  • 时间复杂度:O(N),字符串中的每个字符要么在 O(1) 的时间内被交换到相应的位置,要么因为是空格而保持不动。
  • 空间复杂度:O(1),因为不需要开辟额外的数组。

Python

方法:将字符串分割成单词列表 然后把每个单词反转切片

class Solution(object):
    def reverseWords(self, s):
        return " ".join(word[::-1] for word in s.split(" "))

复杂度分析:

  • 时间复杂度: O(n) ,其中 n 是字符串的长度。
  • 空间复杂度: O(1)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值