代码随想录算法训练营第8天

代码随想录算法训练营第8天 | 344.反转字符串,541. 反转字符串II,替换数字

一、刷题部分

1.1 题目名称

1.1.1 题目描述

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 105
  • s[i] 都是 ASCII 码表中的可打印字符

1.1.2 初见想法

直接交换头尾元素,然后一直往中间走就行。

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

1.1.3 看录后想法

简单题,不多说了。主要是想表达库函数的使用要分情况,一个题目关键步骤应当自己实现,如果不是关键步骤则可以考虑库函数实现。

1.1.4 遇到的困难

🈚️

1.2 题目名称

1.2.1 题目描述

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

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

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"

示例 2:

输入:s = "abcd", k = 2
输出:"bacd"

提示:

  • 1 <= s.length <= 104
  • s 仅由小写英文组成
  • 1 <= k <= 104

1.2.2 初见想法

可以专门写一个反转的函数,传入开头的指针和最后的指针。然后就正常的往下写。

class Solution {
public:
    string reverseStr(string s, int k) {
        int len = s.size();
        while (true) {
            if (len < 2 * k) {
                if (len < k) {
                    reverse(s, s.size() - len, s.size() - 1);
                }
                else {
                    reverse(s, s.size() - len, s.size() - len + k - 1);
                }
                break;
            }
            else {
                reverse(s, s.size() - len, s.size() - len + k - 1);
                len -= 2 * k;
            }
        }
        return s;
    }
    void reverse(string &s, int left, int right) {
        while(left < right) {
            char temp;
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
};

1.2.3 看录后想法

题解给出了一种使用 for 来实现的算法,比我的或许简洁一些。可以仿照着写一下,reverse 函数还是用自己写过的吧。

class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += 2 * k) {
            //长度不足k
            if (i + k - 1 > s.size() - 1) {
                reverse(s, i, s.size() - 1);
                break;
            }
            //长度足够
            reverse(s, i, i + k - 1);
        }
        return s;
    }
    void reverse(string &s, int left, int right) {
        while(left < right) {
            char temp;
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
};

1.2.4 遇到的困难

🈚️

1.3 替换数字

1.3.1 题目描述

题目描述

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

输入示例
a1b2c3
输出示例
anumberbnumbercnumber
提示信息

数据范围:
1 <= s.length < 10000。

1.3.2 初见想法

是一道对字符串操作的问题。可惜字符串使用数组实现的,如果是链表就太方便了。不过即便是数组也有办法。只需要先把数组开的够大,然后从后往前重写元素就行。

//ACM模式
#include <iostream>
#include <string>
using namespace std;

int main(){
    string s;
    cin >> s;
    //遍历一下看看有几个数字
    int numCount = 0;
    for (char c : s) {
        if(c >= '0' && c <= '9') {
            numCount++;
        }
    }
    
    int left = s.size() - 1;
    //直接扩充长度到最后的值
    s.resize(s.size() + 5 * numCount);
    //设置双指针,指向原来的尾部和新的尾部
    //左指针必须在resize前设置好,所以写前面了
    int right = s.size() - 1;
    
    //使用双指针来操作
    for(; left >= 0; left --) {
        if(s[left] >= '0' && s[left] <= '9') {
            s[right--] = 'r';
            s[right--] = 'e';
            s[right--] = 'b';
            s[right--] = 'm';
            s[right--] = 'u';
            s[right--] = 'n';
        }
        else {
            s[right--] = s[left];
        }
    }
    
    cout << s << endl;
}

1.3.3 看录后想法

很多时候都是后序处理会方便很多,本题如果是从前往后地去写那么复杂度是 $O(n^2)$ ,而从后往前就是 $O(n)$ 了。

1.3.4 遇到的困难

🈚️

二、总结与回顾

对字符串进行了初步的了解。觉得难度还可以,继续加油。

posted @ 2025-01-16 20:16  xc0208  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示