《录鼎记》第七章——字符串轮转

今日任务

  • 344.反转字符串
  • 541. 反转字符串II
  • 剑指Offer 05.替换空格
  • 151.翻转字符串里的单词
  • 剑指Offer58-II.左旋转字符串

一、反转字符串

力扣题目链接 (opens new window)

难点在于不能给数组分配额外的空间

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

    }
};

字符转也算是比较熟悉的内容了,一遍过。

题解:

二、反转字符串II

力扣题目链接 (opens new window)

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;
    }
};

题解:代码随想录 (programmercarl.com)

一开始思路不是很对,写了很多,照着题解把第二种情况融合到了第一种情况里面。 

三、替换空格

力扣题目链接 (opens new window)

题目解读:这道题如果不用额外空间的话就难一点。但基本方法是可以确定地——双指针法。

class Solution {
public:
    string replaceSpace(string s) {
        int old = s.size();
        int num = 0;
        for(int i=0;i<old;i++){
            if(s[i]==' '){
                num++;
            }
        }
        s.resize(s.size()+2*num);
        int new1 = s.size();
        for(int i = new1-1,j=old-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;

    }
};

基本算是一遍过,但是后面填数的时候忘了加单引号,找错误还是找的蛮久的。

代码随想录 (programmercarl.com)

四、翻转字符串里的单词

力扣题目链接 (opens new window)

题目解读:在题解里提高了本题的难度,要求不使用辅助空间且空间复杂度要求位O(1)。

class Solution {
public:
       void chuk(string& s){
            int num = 0;
            for(int i = 0;i<s.size();i++ ){
                if(s[i] != ' '){
                    if(num!=0){
                        s[num++]=' ';
                    }
                    while(i<s.size()&&s[i]!=' '){
                        s[num++]=s[i++];
                    }
                }
            }
            s.resize(num);

        } 
       void reversed(string& s,int begin,int end){
           for(int i=begin,j=end;i<j;i++,j--){
               swap(s[i],s[j]);
           }

       }
    string reverseWords(string s) {
        chuk(s);
        reversed(s,0,s.size()-1);
        int j =0;
        for(int i =0;i<=s.size();i++){
            if(i==s.size()||s[i]==' ')
            {
                reversed(s,j,i-1);
                j=i+1;
            }
        }
        return s;
    }
};

         有两个地方比较难以理解,首先是在removeExtraSpace也就是移除空格的时候,题解里德算法将buslow非零的情况拿出来,在这种情况下是要接一个空格然后接单词的,所以有

if (slow != 0) s[slow++] = ' '

后面把头部和其他的地方算作一种。

           另一个地方是在下面的主函数里面,在一个for循环中,i等于了s.size(),一般情况下,这是不允许的(因为可能造成溢出)。但在这里,为了不让句子末尾的单词需要单拎出来使用参数有变化的reverse函数,在这个值上,下面的if用或运算避免了这种情况,因为if判断语句中,如果前面的运算可以确定此次判断的值(此处i==s.size()时直接为true进入if下面的语句中),是不会再向后进行运算,直接执行或跳过。此处题解利用了这一点,避免了溢出 。

代码随想录 (programmercarl.com)

五、左旋字符串

力扣题目链接 (opens new window)

题目解读:此题本身还是比较简单的,但是在题解中提升了本题的难度——不能申请额外的空间,只能在串上操作。

这样的话想要达到此题的目的还是比较难的。

题解中提出了这样的解法:1、反转区间为前n的子串

                                           2、反转区间为n到末尾的子串

                                           3、反转整个字符串

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;



    }
};

一开始思路错了,以为还得用到swap,没想到3个reverse直接结束。

不过在题解中发现一个比较有趣的解法。

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        int len =s.size();

        s.resize(len+n);

        for(int i=0;i<n;i++){
            s[len++] =s[i];
        }

        s.erase(0,n);
        return s;
    }
};

虽然用了额外空间了,但是这涉及到字符串轮转。

用了一个半点吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值