代码随想录训练营Day8|力扣344、541反转字符串、卡码网54替换数字、151翻转字符串里的单词、卡码网55右旋转字符串

1.反转字符串

题目链接/文章讲解/视频讲解: 代码随想录

代码:(双指针法)

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() - 1;
        int t = 0;
        // 区间是左闭右闭
        while(left <= right){
            t = s[left];
            s[left] = s[right];
            s[right] = t;

            left++;
            right--;
        }
    }
};

 思路:这题简单的。 但是我又脑抽写成了交换下标。。。。

2.反转字符串II

题目链接/文章讲解/视频讲解: 代码随想录

代码:

class Solution {
public:
    string reverseStr(string s, int k) {
        // 每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
        for(int i = 0;i < s.size(); i += 2*k){
            // 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
            if(i + k <= s.size()){
                reverse(s.begin() + i,s.begin() + i + k);
            }else{
                // 如果剩余字符少于 k 个,则将剩余字符全部反转。
                reverse(s.begin() + i,s.end());
            }
        }
        return s;
    }
};

 思路:每2k个字符长度要做一次处理,所以可以直接让遍历后的i += 2*k,for循环的技巧。

还有就是,这个条件判断写着有点别扭。判断是看i+k的大小的,循环就是看i+2k的大小了。

3.替换数字

题目链接/文章讲解: 代码随想录

代码: 

# include <iostream>
using namespace std;
int main(){
    string s;
    while(cin >> s){
        // 数组从前向后遍历会影响到后续元素的移动,因此我们从后向前遍历
        // sOld是我们从后往前遍历原数组要用到的
        int sOld = s.size() - 1;
        int count = 0;
        // 统计字符串里有多少数字,方便后续扩容
        for(int i = 0;i < s.size();i++ ){
            if(s[i] >= '0'&& s[i] <= '9'){
                count++;
            }
        }
        // 给字符串扩容,number比单个的数字多5个字节
        s.resize(s.size() + count * 5);
        // sNew是遍历新数组要用到的
        int sNew = s.size() - 1;
        
        for( ;sOld >= 0;sOld--){
            if(s[sOld] >= '0'&&s[sOld] <='9'){
                s[sNew--] = 'r';
                s[sNew--] = 'e';
                s[sNew--] = 'b';
                s[sNew--] = 'm';
                s[sNew--] = 'u';
                s[sNew--] = 'n';
            }else{
                s[sNew--] = s[sOld];
            }
        }
        cout << s << endl;
    }
}

思路:从后向前遍历数组可以减少时间复杂度。自己不熟悉这种acm格式写题。

4.翻转字符串里的单词

题目链接/文章讲解/视频讲解: 代码随想录

代码:

class Solution {
public:
    void removeExtraSpaces(string &s){
        // 这里一定要注意判断条件是原字符串还是新字符串
        int slow = 0;
        for(int fast = 0;fast < s.size();fast++){
            // fast去遍历原字符串,slow来填新字符串
            // 我们是要去除多余的空格,所以要填到新字符串的元素不是空格
            if(s[fast] != ' '){
                // 在单词的开头,还是要填一个空格
                if(slow != 0)
                    s[slow++] = ' ';
                // 将原字符串的字母搬运到新字符串中
                while(fast < s.size() && s[fast] != ' '){
                    s[slow++] = s[fast++];
                }
            }
        }
        s.resize(slow);
    }
    void reverse(string &s,int start,int end){
        while(start < end){
            int i = s[start];
            s[start] = s[end];
            s[end] = i;

            start++;
            end--;
        }
    }
    string reverseWords(string s) {
        removeExtraSpaces(s); // 去除多余的空格
        reverse(s,0,s.size() - 1); // 将整个字符串翻转
        int start = 0; // 记录每个单词的开始位置
        //再将每一个单词翻转
        for(int i = 0;i <= s.size();i++){
            if(i == s.size()||s[i] == ' '){ 
                //为了让结束位置也符合我们循环里的步骤,i要遍历到字符串外
                reverse(s,start,i - 1); // s[i]是空格,我们翻转的是单词,所以传入s[i-1]
                start = i + 1; // 空格的下一个元素就是下一个单词的开始位置
            }
        } 
        return s;
    }
};

状态:我真的要被bug死了。。。

首先是分不清fast和slow,在条件判断的时候用哪个;其次是翻转的函数里,我又把值和小标弄混了;然后是在翻转单词的时候,弄错了传入函数的参数(s[i]是空格,我只需要把单词传进去);然后是搞混了最后寻找空格的遍历函数的边界条件。。。。。

4.右旋转字符串

题目链接/文章讲解:

代码: 

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
    int n;
    string s;
    cin >> n;
    cin >> s;

    reverse(s.begin(),s.end());
    reverse(s.begin(),s.begin() + n);
    reverse(s.begin() + n,s.end());

    cout << s << endl;

} 

状态:

救命,一直写错单词,reverse,reverse,reverse,重要的单词打三遍。。。

题目的思路就是,局部旋转+整体旋转。局部怎么转,自己可以试着画图。只要是让指定的区间翻转就行了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值