代码随想录算法训练营第七天● 344.反转字符串● 541. 反转字符串II● 剑指Offer 05.替换空格● 151.翻转字符串里的单词● 剑指Offer58-II.左旋转字符串

344.反转字符串。就头和尾相对移动交换就行。交换用swap()函数,也可以用中间量自己写。

一个函数实现反转就是:

void reverse(string& s,int f,int e)
    {
        if (f < 0 || e < 0 || f >= s.size() || e >= s.size()) {
    return;
}

        for(int i=f;i<=(e+f)/2;++i)  //[f,**]注意是闭区间
        {
            swap(s[i],s[f+e-i]);
        }
    }

541.规律就是每隔2k个字符就反转前k个,所以一个循环就够了,主要是循环之内的那个交换左右反转子字符串的循环,j的边界条件要写对,还有交换元素的下标要写对。

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=2*k)
        {
            int len=k<(s.size()-i)?k:(s.size()-i);
            for(int j=i;j<i+len/2;++j)
            {
                swap(s[j],s[2*i+len-j-1]);
            }
        }
        cout<< s;
        return s;
    }
};

剑指Offer 05.替换空格。双指针法一个循环搞定。

class Solution {
public:
    string reverseStr(string s) {
        int count=0;
        for(int i=0;i<s.size();++i)
        {
            if(s[i]==' ')count++;
        }
        int a=s.size()-1;
        s.resize(s.size()+count*2);
        int b=s.size()-1;
        cout<<a<<"  "<<b<<endl;
        while(a<b)
        {
            if(s[a]==' ')
            {
                s[b--]='0';
                s[b--]='2';
                s[b--]='%';
                a--;
            }
            else{
                s[b--]=s[a--];
            }
        }
        return s;
    }
};

151、先整体反转,再每个单词反转就OK,但是自己写的总是显示越界错误:

class Solution {
public:
    void reverse(string& s,int f,int e)
    {
        if (f < 0 || e < 0 || f >= s.size() || e >= s.size()) {
    return;
}

        for(int i=f;i<=(e+f)/2;++i)  //[f,**]注意是闭区间
        {
            swap(s[i],s[f+e-i]);
        }
    }
    string reverseWords(string s) {
        int a=0,c=s.size()-1,b=0;
        while (a < s.size() && s[a] == ' ') a++;
        while (c >= 0 && s[c] == ' ') c--;
        s.resize(c+1);
        cout<<s<<endl;
        int newIndex = 0;
for (int i = 0; i < s.size() - a; ++i) {
    s[newIndex++] = s[i + a];
}
s.resize(newIndex);

        s.resize(s.size()-a);
        cout<<s<<endl;
        reverse(s,0,s.size()-1);
        c=s.size()-a;
        while(b<=c)
        {
            while(s[b]!= ' ' && b<=c)
            {
                b++;
            }
            reverse(s,a,b-1);
            cout<<s<<endl;
            a=++b;
        }
        return  s;
    }
};

删除空格的时候变量用多了。其实还是快慢指针的思想,用一个index和一个i变量完成中间和两边所有多余空格的删除。注意在i不是空格的时候用把i指的那个元素赋给slow的那个元素,中间应该有的空格是判断slow不是第一个单词的话加上去,那么最后resize(slow)就行了,不会有错误。那个if语句里面也能统计单词个数。

class Solution {
public:
    void reverse(string& s,int f,int e)
    {
        for(int i=f;i<=(e+f)/2;++i)  //[f,**]注意是闭区间
        {
            swap(s[i],s[f+e-i]);
        }
    }
    string reverseWords(string s) {
        int a=0,c=s.size()-1,b=0;
        while (a < s.size() && s[a] == ' ') a++;
        while (c >= 0 && s[c] == ' ') c--;
        cout<<"c is:"<<c<<endl;
        int slow=0,count=0;
        for(int i=0;i<s.size();++i)
        {
            if(s[i]!=' ')
            {
                count++;
                if(slow!=0)s[slow++]=' ';
                while(s[i]!=' '&&i<s.size())
                {
                    s[slow++]=s[i++];
                }
            }
        }
        cout<<"处理后  "<<count<<"  "<<s<<endl;
        s.resize(slow);
        reverse(s,0,s.size()-1);
        a=0;
        while(b<s.size())
        {
            while(s[b]!= ' ' && b<s.size())
            {
                b++;
            }
            reverse(s,a,b-1);
            cout<<s<<endl;
            a=++b;
        }
        return  s;
    }
};

58、左旋字符串:跟上面的题一样的思路,不过是先整体反转再局部反转。右旋也是一样,先整体反转再局部反转。

原下标(在下标前省略了a,0是指a0.):

0,1,2,3,4,……,n-1,n

整体反转:

n,n-1,…n-k+1,n-k…,4,3,2,1,0

局部反转。

n-k+1,……,n-1,n,0,1,2,3,4……n-k

这样就把后面k个一起挪到前面去了,把前面n-k+1个挪到后面去了。

总结:所以字符串的反转是很多问题的基本操作,一定注意。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值