代码随想录算法训练营第八天 | 344.反转字符串、541. 反转字符串II、卡码网:54.替换数字、151.翻转字符串里的单词、卡码网:55.右旋转字符串

344.反转字符串

题目链接:https://leetcode.cn/problems/reverse-string/
文章讲解:https://programmercarl.com/0344.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html
视频讲解:https://www.bilibili.com/video/BV1fV4y17748
状态:做了出来

思路

就相向双指针就Ok了

代码实现

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() - 1;
        while(left <= right){
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left ++;
            right --;
        }
    }
};

541.反转字符串Ⅱ

题目链接:https://leetcode.cn/problems/reverse-string-ii/
文章讲解:https://programmercarl.com/0541.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2II.html
视频讲解:https://www.bilibili.com/video/BV1dT411j7NN
状态:思想对了,没处理好

思路

先审题,我们会发现当尾部,不足n个,全部反转,尾部>=n个,反转前面n个

代码实现

①没有用库函数

class Solution {
public:
    string reverseStr(string s, int k) {
            for(int i = 0; i < s.size(); i += 2 * k){
                if(s.size() - i < k){
                    for(int left = i, right = s.size() - 1;left<=right;){
                        swap(s[left], s[right]);
                        left++;
                        right--;
                    }
                }else{
                    for(int left = i, right = i + k - 1; left <= right;){
                        swap(s[left], s[right]);
                        left++;
                        right--;
                    }
                }
                
            }
            return s;
    }
};

②使用库函数,注意reverse的用法,是左闭右开的

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

卡玛网:54.替换数字

题目链接:https://kamacoder.com/problempage.php?pid=1064
文章讲解:https://programmercarl.com/kama54.%E6%9B%BF%E6%8D%A2%E6%95%B0%E5%AD%97.html
状态:没做出来

思路

在原数组上进行操作,先对数组进行扩容,将里面所有的数字都再加5个
然后一个指针指向原内容最后一个,一个指针指向新数组最后一位,进行判断并填充

代码实现

注意while(cin>>s)的用法

#include <iostream>
using namespace std;

int main(){
    string s;
    while(cin>>s){
        int count = 0;
        int sOldSize = s.size();
        for(int i = 0; i < s.size(); i++){
            if(s[i] > '0' && s[i] < '9'){
                count ++;
            }
        }
        s.resize(s.size() + 5 * count);
        int sNewSize = s.size();
        for(int j = sNewSize - 1, i = sOldSize; j >= 0; j--,i--){
            if(s[i] > '0' && s[i] < '9'){
                s[j] = 'r';
                s[j - 1] = 'e';
                s[j - 2] = 'b';
                s[j - 3] = 'm';
                s[j - 4] = 'u';
                s[j - 5] = 'n';
                j -= 5;
            }else{
                s[j] = s[i];
            }
        }
        cout << s << endl;
    }
}

151.反转字符串里的单词

题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/
文章链接:https://programmercarl.com/0151.%E7%BF%BB%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E7%9A%84%E5%8D%95%E8%AF%8D.html
视频讲解:https://www.bilibili.com/video/BV1uT41177fX
状态:

思路

先把整个字符串反转,再去反转里面的每个单词,然后再去除多余的空格,在去除空格时,去用快慢指针,快指针先找到第一个单词的首字母,更新slow,注意slow在每个单词后要留空,可以在遍历单词循环前实现,接着就是遍历单词了

代码实现过程中遇到的困难

reverse的实现,单词最后一个的情况,反转单词时start的运用

代码实现

class Solution {
public:
    string reverseWords(string s) {
        //全部反转
        reverse(s.begin(), s.end());
        //反转一遍单词
        int start = 0;
        for(int i = 0; i <= s.size(); i++){
            //找出单词
            if(s[i] == ' ' || i == s.size()){
                reverse(s.begin() + start, s.begin() + i);
                start = i + 1;
            }
            
        }
        //去除空格
        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);
        return s;
    }
};

卡码网:55.右旋转字符串

题目链接:https://kamacoder.com/problempage.php?pid=1065
文章讲解:https://programmercarl.com/kama55.%E5%8F%B3%E6%97%8B%E5%AD%97%E7%AC%A6%E4%B8%B2.html
状态:不会

思路

联想上一道,可以先整体再局部,当然也可以先局部后整体

代码实现

①先整体再局部

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

②先局部再整体

#include <iostream>
#include <algorithm>
using namespace std;

int main(){
    int n;
    string s;
    cin >> n;
    cin >> s;
    
    reverse(s.begin(), s.begin() + s.size() -n);
    reverse(s.begin() + s.size() - n, s.end());
    reverse(s.begin(), s.end());
    cout << s;
}

收获

反转经常有先整体再局部的思想

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值