代码随想录算法训练营Day09||Leecode151.反转字符串中单词、卡码网55.右旋转字符串

 一、反转字符串中单词

        本题上来我想到了用空格检索作为分界点,然后进行反转,但是想不到如何让单词整体反转的同时,还要保留空格。这道题涉及的知识点真的非常多,也非常有意思。

        第一,需要去掉多余的空格(包括开头的空格、后尾的空格、以及中间多余的空格)。去掉空格又用了三种不同的方法:

                1.开头的空格先让快指针平移,直到检索到第一个不为空格的值,然后开始进行字符串的覆盖

                2.去除中间空余部分的空格包含在了用快慢指针覆盖这一过程中,具体操作是检测到快指针当前指向空格,并且它的前方也是空格,利用continue跳出本次循环,什么操作都不做。

                3.尾部空格的去除运用了缩小字符串长度直接对多余空间进行删除。具体操作是,用慢指针检索尾部是否有空格(这里的空格一定只有一个,不会存在多个,因为第二步覆盖操作时已经利用continue去掉了连续的空格),如果有空格,就把字符串利用resize重新定义长度。这里有一个细节是,low指针在前面覆盖操作的时候,最后有一步low++的自增了,所以在下表中,指向的是末尾元素的后一位,因此检查最后一位是不是空格的指针是low-1指针而不是low指针。最后用resize缩小长度时,如果有空格就变成low-1,如果不是空格长度就是low。具体可以参考下图:

        第二、在把所有的字符串换成统一格式以后,现在字符串的结构都是“abcd dc ed df”了,现在需要做的操作是先将整个字符串反转,变成“fd de cd dcba”。然后再以空格和a后面的末尾指针(s.size())为分界,进行局部反转,变成“df ed dc abcd”。反转时,需要用自己编写的reverse()函数,这里有一个注意点是:reverse函数传参string&s,int start,int end。s前面要加&符号,因为要对原字符串进行操作,因此需要带回原值。 

class Solution {
public:
    void reverse(string&s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }
    string reverseWords(string s) {
        int low=0;
        int fast=0;
        //去前导空格
        while(fast<s.size()&&s[fast]==' '){
            fast++;
        }
        //去中间空格
        for(;fast<s.size();fast++){
            if(s[fast]==' ' && s[fast-1]==' '){
                continue;
            }
            else{
                s[low++]=s[fast];
            }
        }
        //去末尾空格
        
        if(low<s.size()&&s[low-1]==' '){//low在上一步赋值的时候有自增,也就是说,low目前指向的是空格之后一位
            s.resize(low-1);
        }
        else{
            s.resize(low);
        }
        //字符串倒序
        reverse(s,0,s.size()-1);
        for(int i=0,j=0;i<=s.size();i++){
            if(i==s.size()||s[i]==' '){
                reverse(s,j,i-1);
                j=i+1;

            }
        }

        return s;
    }
};

二、右旋转字符串

        类似反转单词,前者是用空格做分界,后者是用长度做分界,这里还运用了algorithm库函数中的reverse,利用迭代器直接进行反转,比用手写的用长度反转更便捷

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
    int k;
    string s;
    cin>>k;
    cin>>s;
    
    reverse(s.begin(),s.end());
    reverse(s.begin(),s.begin()+k);
    reverse(s.begin()+k,s.end());
    
    
    cout<<s<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值