LeetCode 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 <= 10^4
  • s 包含英文大小写字母、数字和空格 ' '
  • s 中 至少存在一个 单词

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

思路

本题的主要解题思路可以分为三步:

  1. 移除字符串首部、中间、尾部的多余空格。
  2. 将整个字符串反转。
  3. 将字符串的每个单词反转。

在第1步笔者使用的是快慢指针法,让快指针去寻找新字符串的字符,慢指针则记录新字符串的最后一个字符。中间空格的处理比较麻烦,需要保留一个空格,此时当遇到空格+空格的情况时,让fast++,否则交换s[slow]和s[fast],那么当遇到字符+空格的情况时,那个空格便会被保留下来,从而实现删除中间多余的空格。不过最后一个单词后面的空格也会被保留下来,在去除尾部空格的时候需要注意。

Python有好用的函数可以直接去除空格和切割单词,将单词分割开后再反转,最后拼接即可。

代码

C++版:

class Solution {
public:
    string reverseWords(string s) {
        // 在C++中string可被修改,因此考虑使用O(1)额外空间的解法
        // 1.去除多余空格,使用快慢指针法
        // 2.反转整个字符串
        // 3.反转字符串中的每个单词
        int slow=0;
        int fast=0;
        // 将fast移动到第一个非空格元素
        while(fast<s.size() && s[fast]==' '){
            fast++;
        }
        // 快指针负责寻找新数组的元素
        // 去除首部和中间的空格
        while(fast<s.size()){
            // 对于中间的空格,只有是连续的2个空格以上的情况时,fast才会跳过
            if(fast-1>=0 && s[fast]==' ' && s[fast-1]==' '){
                fast++;
            }
            else{
                // 连续的空格段中,第一个空格会被加入到新字符串中
                // 注意会导致新字符串的最后一位必然是空格
                s[slow++]=s[fast++];
            }
            
        }
        // 去除末尾的空格
        if(slow-1>=0 && s[slow-1]==' '){
            s.resize(slow-1);
        }else{
            s.resize(slow);
        }

        // 反转整个字符串
        reverse(s.begin(),s.end());
        // 反转每个单词
        int start=0; // 记录单词开始位置
        for(int i=0;i<=s.size();i++){
            if(i==s.size() || s[i]==' ' ){
                reverse(s.begin()+start,s.begin()+i);
                start=i+1;
            }
        }
        return s;

    }
};

Python版:

class Solution:
    def reverseWords(self, s: str) -> str:
        # 去除多余空格,将字符串拆分为单词,即转换成列表类型
        words = s.split()

        # 反转单词
        left, right = 0, len(words) - 1
        while left < right:
            words[left], words[right] = words[right], words[left]
            left += 1
            right -= 1

        # 将列表转换成字符串
        return " ".join(words)

需要注意的地方

1.str.reverse(str.begin(),str.end())中str.end()指的是字符串str最后一个字符的下一个位置。

2.erase()操作的时间复杂度是O(n)。

3.Python和Java都不能在字符串上修改,需要申请新空间,而C++可以在字符串上修改,因此能用O(1)的空间完成本题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值