代码随想录day8|反转字符串、反转字符串II、替换空格、翻转字符串里的单词、左旋转字符串

反转字符串

这道题我们使用双指针法,一个指针指向首元素,一个指针指向末尾元素,相互交换数值,然后首指针加1,末尾指针减1,继续交换。

class Solution {
public:
    void reverseString(vector<char>& s) {
        for(int i = 0,j = s.size()-1;i < j;i++,j--){
            swap(s[i],s[j]);
        }
    }
};

反转字符串II

 这道题相较于前面一题有点难度,我们需要首先反转2k个字符中k个元素,然后又过2k个继续反转k个元素,直到剩余字符小于k个或者2k个。因为我们每次是隔着2k个,因此遍历函数的时候,我们使用i++过于繁琐,我们可以直接使用i += (2*k)。只要当前最后字符的剩余字符大于等于k,那么我们就可以直接反转k个元素。因此前2k个元素和最后一组数据可以组合起来,若是最后剩余字符小于k,直接反转里面有的元素就可以。

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i = 0;i < s.size();i += (2*k))
        {
            if(i + k <= s.size()){
                reverse(s.begin()+i,s.begin()+i+k);
            }else{
                reverse(s.begin()+i,s.end());
            }
        }
        return s;
    }
};

替换空格

 首先这道题,我们将字符串中每个空格都替换成%20,我们需要在不开辟新的辅助空间的情况下我们需要扩充数组的长度。这道题我们使用双指针法,用一个指针i指向原始长度的末尾,用另一个指针j指向新长度的末尾。我们预先留出扩充好的数组的长度,从后往前填充。

这里不使用从前往后填充,就是因每一次数组的长度都会变化。

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0;
        int sOldSize = s.size();
        for(int i = 0;i < s.size();i++){
            if(s[i] == ' '){
                count++;
            }
        }
        s.resize(s.size() + (2*count));
        int sNewSize = s.size();
        for(int j = sOldSize-1,i = sNewSize-1;j<i;i--,j--)
        {
            if(s[j] != ' ')
            {
                s[i] = s[j];
            }else
            {
                s[i] = '0';
                s[i-1] = '2';
                s[i-2] = '%';
                i -= 2;
            }
        }
        return s;
    }
};

只要j的位置上不为空,那么就把j位置上的那个数放到i位置上,如果为空,那就让i的前三位都补充上%20。

翻转字符串里的单词 

这道题我们不增加额外空间,基本处理思路是:先移除多余的空格元素、然后再将整个字符串进行反转、然后将每个单词进行反转。 

class Solution {
public:
    void reverseExtraSpaces(string& s){
        int slow = 0;
        for(int i = 0;i < s.size();i++)
        {
            if(s[i] != ' ')//只有当i不指向空格才能接下来操作
            {
                if(slow != 0)//第一个单词前面不要空格,在接下来的每一个单词前面都加上一个空格
                {
                    s[slow] = ' ';
                    slow++;
                }
            }
            while(i < s.size() && s[i] != ' ')//补全每个单词,遇到下一个空格,就说明单词结束
            {
                s[slow] = s[i];
                i++;
                slow++;
            }
        }
        s.resize(slow);//重新设置字符串长度
    }
    
    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) {
        reverseExtraSpaces(s);
        reverse(s,0,s.size()-1);
        int start = 0;
        for(int i = 0;i <= s.size();i++)
        {
            if(i == s.size() || s[i] == ' ')
            {
                reverse(s,start,i-1);
                start = i + 1;
            }
        }
        return s;
    }
};

左旋转字符串 

 这道题和前面一道题很类似,基本的解题思路是:我们先反转前区间前n个子串,再反转后面剩下的子串,最后再反转整个串。举个例子来说,abcdefg,n=2,先反转前两,就变成bacdefg,再反转后面5个就变成bagfedc,最后整体反转就是cdefgadb,这样以来就完成了我们的操作。

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(),s.begin()+n);
        reverse(s.begin()+n,s.end());
        reverse(s.begin(),s.end());
        return s;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值