【C++编程能力提升】

一、344 反转字符串

题目链接:344 反转字符串

核心:双指针,首尾交换,并依次向中间移动。

    void reverseString(vector<char>& s) {
    //双指针,首尾交换,然后同时向中间移动
    int left=0;
    int right=s.size()-1;
    while(left<right)
    {//left==right时指向同一个元素,无需交换,故退出循环
        swap(s[left],s[right]);
        left++;
        right--;
    }
    }

二、541 反转字符串II

题目链接:541 反转字符串II

核心:指定范围的字符串反转的核心确定此范围,本题遍历时以2k为步长,每遍历2k个字符,判断剩余字符是少于k个还是大于等于k个,前者需全部反转,即范围是[i,end],后者仅反转前k个字符,即范围是[i,i+k-1]。

    void reverse(string& s,int start,int end)
    {//实现s的反转
        while(start<end)
        {
            swap(s[start],s[end]);
            start++;
            end--;
        }
    }
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=2*k)
        {//遍历s,关键是“每计数至2k”的处理,其实用步长实现即可!
            if(i+k<=s.size())
            {//剩余字符>=k个(也存在剩余字符>=2k情况,不过也需要反转前k个,故归为一类)
                reverse(s,i,i+k-1); //反转前k个字符,完成后进入下一个loop
                continue;
            }
            //剩余字符小于k个,全部反转
            reverse(s,i,s.size()-1);           
        }
        return s;
    }

三、剑指Offer 05 替换空格

题目链接:剑指Offer 05 替换空格

核心:要将空格填充为特殊字符,首先计算空格数,然后扩充原字符串大小为填充特殊字符后的大小,最后从后往前依次遍历字符串,遇到空格则填充,否则直接复制元素。

    string replaceSpace(string s) {
    //先扩充s大小,再从后往前遍历
    int len=s.size();
    int cnt=0;
    for(char ch:s)
    {//计算s中的空格数
        if(ch==' ')
            cnt++;
    }
    s.resize(s.size()+cnt*2);
    int newlen=s.size();
    int j=len-1;        //j指向原字符串
    for(int i=newlen-1;i>=0;i--)
    {
        if(s[j]!=' ')
        {//不是空格直接复制即可
            s[i]=s[j];
        }
        else
        {//遇到空格则插入“%20”
            s[i]='0';
            s[i-1]='2';
            s[i-2]='%';
            i-=2;   //需要向前移动2步,即此时i指向'%'
        }
        j--;    //完成一次i的处理j需要向前移动1位
    }
    return s;
    }

四、151 反转字符串中的单词

题目链接:151 反转字符串中的单词

核心:首先移除多余空格,然后反转整个字符串,最后反转单词,移除多余空格和反转字符串可作为2个子函数,被主函数调用实现,减少主函数的复杂度。

    void reverse(string& s,int start,int end)
    {//完成对字符串s从start开始到end结束之间所有元素的反转
        while(start<end)
        {
            swap(s[start],s[end]);
            start++;
            end--;
        }
    }

    void removeExtraspace(string& s)
    {//双指针,fast遍历原s,slow指向有效元素得到新的s
        int slow=0;
        for(int fast=0;fast<s.size();++fast)
        {
            if(s[fast]!=' ')
            {
                if(slow>0) 
                    s[slow++]=' ';  //遇到下一个单词的开始,需要增加一个空格
                while(fast<s.size() && s[fast]!=' ')
                    s[slow++]=s[fast++];
            }
        }
        s.resize(slow); //循环结束时slow++,因此slow即新s的长度
    }

    string reverseWords(string s) {
    //先去除多余空格,再将字符串整体反转,最后对单个单词反转,遇到空格则表示一个单词结束
        removeExtraspace(s);//去除多余空格
        int len=s.size();
        reverse(s,0,len-1);  //整体反转
        int start=0;
        for(int i=0;i<=len;++i)
        {//遍历s,对单个单词反转
            if(i==len || s[i]==' ')
            {//找到一个单词,或者整个字符串就一个单词,即不存在空格
                reverse(s,start,i-1);   //注意i-1最终指向len-1的元素,故i<=len
                start=i+1;  //更新start,即下一个单词的开始
            }
        }
        return s;
    }

五、剑指Offer58-II 左旋转字符串

题目链接:剑指Offer58-II 左旋转字符串

核心:首先反转区间为前n的子字符串,然后反转区间为n至末尾的子字符串,最后反转整个字符串。

    void reverse(string& s,int start,int end)
    {
        while(start<end)
        {
            swap(s[start],s[end]);
            start++;
            end--;
        }
    }
    string reverseLeftWords(string s, int n) {
    //先反转前n个元素,再反转后s.size()-n个元素,最后整体反转
    reverse(s,0,n-1);
    reverse(s,n,s.size()-1);
    reverse(s,0,s.size()-1);
    return s;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值