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

力扣题目链接:344. 反转字符串

这个题目非常简单,它必须原地修改输入数组,并且使用O(1)的额外空间解决这个问题。

显然,我们得先知道要经过多少次交换。字符数组长度为n,不管n为奇数还是偶数,我们都可以经过n/2次交换。然后需要创建一个临时字符变量,用来做交换。

步骤如图:

代码如下:

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

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

这个题并不是难题,但是题目有点难懂。还有就是,不要陷入思维定势。比如用for循环去遍历元素,我们不能只想着用i++去一个一个遍历。还可以跳着遍历。就比如这个题,我们可以每次只遍历第2k个元素。也就是 i += 2k。因为这题的要求是每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。我们直接只遍历第2k个元素,这样的话可以省掉很多步骤,省掉用计数器去记录。

然后本题还需要进行判断。如果剩余字符少于k个,反转所有剩下的字符。

如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余字符保持原样。

也就是 i+k>s.size()那就是反转后续所有元素。否则反转前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;
    }
};

力扣题目链接:LCR 122. 路径加密

代码随想录里面的链接是这个,这题过于简单了,一个for循环搞定。

代码如下:

class Solution {
public:
    string pathEncryption(string path) {
        for(int i =0;i<path.size();i++)
        {
            if(path[i]=='.')
            {
                path[i] = ' ';
            }
        }
        return path;
    }
};

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

这个题刚开始看的时候毫无思路,看了代码随想录的讲解,总结了一下解法。

总体思路为:

我们可以先将字符串中的多余空格全部去除,然后反转整个字符串,最后将每个单词反转即可。

但是这个题目难点,细节还是挺多的。

首先就是如何将多余的空格去除,对于去除字符串中的字符(不管是空格还是别的),我们都可以参考前面数组移除元素的做法。使用双指针法,直接对字符串进行操作。但是这个题目因为不是去除所有的空格而是去除多余空格,所以我们需要控制空格的删除,而不是将所有空格都删除。

所以我们可以手动控制,就是在每个单词后面手动加一个空格。具体细节如下:

具体代码如下:

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]);
        }
    }
    void deletespace(string &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);
    }
    string reverseWords(string s) {
       deletespace(s);
       reverse(s,0,s.size()-1);
       int start = 0;
       for(int i =0;i<=s.size();i++)
       {
           if(s[i]==' '||i==s.size())
           {
               reverse(s,start,i-1);
               start = i+1;
           }
       }
       return s;
    }
};

LCR 182. 动态口令

我的想法是,创建一个新的字符串,然后写两个for循环将题目中的字符串按照要求放到新字符串里面。

代码如下:

class Solution {
public:
    string dynamicPassword(string password, int target) {
        string temp = password;
        for(int i = 0;i<password.size()-target;i++)
        {
            temp[i] = password[target+i];
        }
        int j = 0;
        while(target--)
        {
            temp[password.size()-target-1] = password[j];
            j++;
        }
        return temp;
    }
};

后面看了代码随想录的讲解,恍然大悟。

其实这题可以先将前target个元素反转,然后将target后面的元素反转,最后反转所有字符串。

代码如下:

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值