leetcode:151. 颠倒字符串中的单词

题目来源

题目描述

在这里插入图片描述
在这里插入图片描述

题目解析

进阶要求(原地 解法)

不能使用辅助空间之后,那么只能在原字符串上下功夫了。

思路:源字符串为:"the sky is blue "

  • 移除多余空格:“the sky is blue”
  • 字符串反转:“eulb si yks eht”
  • 单词反转:“blue is sky the”
    在这里插入图片描述
class Solution {
public:
    //反转字符串
    void reverse(string& s,int start,int end){
        while(start<end){
            swap(s[start++],s[end--]);
        }
    }
    //移除多余空格,利用快慢指针
    void removeExtraSpaces(string&s){
        int slow=0,fast=0;
        //移除开始位置的空格
        while(s[fast]==' '){
            fast++;
        }
        //移除中间位置多余的空格
        while(fast<s.size()){
            if(fast>0 && s[fast]==' ' &&s[fast-1]==' '){
                fast++;
            }
            else{
                s[slow]=s[fast];
                slow++;
                fast++;
            }
        }
        //如果末尾仅有一个空格,则上述无法将该空格移除;如果末尾有很多空格,则上述将保留一个空格,也不符合要求;所以最终可能的情况有二:末尾有一个空格/末尾无空格
        
        if(slow-1>0 && s[slow-1]==' '){
            slow--;
        }
        s.resize(slow);
    }
        
    string reverseWords(string s) {
        //step1.移除多余空格
        removeExtraSpaces(s);
        //step2.反转整个字符串
        reverse(s,0,s.size()-1);
        //step3.依次反转每个单词
        int start=0;
        for(int i=0;i<s.size();i++){
            if(s[i]==' '){
                reverse(s,start,i-1);
                start=i+1;
            }
            if(i==s.size()-1){
                reverse(s,start,i);
            }
        }
        return s;
    }
}

API

class Solution {
public:
    string reverseWords(string s) {
        istringstream sin(s);
        string ans, word;
        while(sin>>word){
            ans = " " + word + ans;
        }
        return ans.substr(1, ans.size()-1);
    }
};

一次遍历(辅助空间)

class Solution {
public:
    string reverseWords(string s) {
        if(s.empty()){
            return "";
        }

        int L = 0, R = s.size() - 1;
        std::string ans;
        while (L <= R){
            while (L <= R && s[L] == ' '){
                L++;
            }
            int start = L;
            while (L <= R && s[L] != ' '){
                L++;
            }
            int len = L - start;  // 'a '
            if(len != 0){
                std::string tmp = s.substr(start, len);
                ans = ans.empty() ? tmp : tmp + " " + ans;
            }
        }
        return ans;
    }
};

类似题目

题目思路
leetcode:61. 旋转链表,每个节点右移k个位置 Rotate List先遍历整个链表获得链表长度n,然后把链表头部和尾部连接起来,在往后走n - k % n个节点就到达新链表的头结点的前一个节点,这时断开链表即可
leetcode:189. 旋转数组,每个数组右移k个位置 Rotate Array多次反转:先反转全部,然后反转前k个,最后反转剩余的;下标连环怼;使用临时数组
leetcode:151. 给定字符串, 反转字符串中的单词 Reverse Words in a String源字符串为:"the sky is blue ";移除多余空格:“the sky is blue”;字符串反转:“eulb si yks eht”;单词反转:“blue is sky the”
leetcode:186. 给定char数组,翻转字符串里的单词 II Reverse Words in a String II先把每个单词翻转一遍,再把整个字符串翻转一遍,或者也可以调换个顺序,先翻转整个字符串,再翻转每个单词
leetcode:557. 给定字符串, 反转字符串中的单词 III Reverse Words in a String III可以用字符流处理类stringstream来做:按顺序读入每个单词进行翻转即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值