代码随想录刷题第八天

今天进入字符串。第一题是反转字符串https://leetcode.cn/problems/reverse-string/description/,首先想到的是双指针一个left一个right,调用一下swap函数。比上一章哈希表简单一些。

class Solution {
public:
    void reverseString(vector& s) {
    int left = 0;
    int right = s.size() - 1;
    for(int i = 0; i < s.size(); i++){
        if(left <= right){swap(s[left], s[right]);
        left++;
        right--;}
    }
    }
};

第二题还是反转字符串https://leetcode.cn/problems/reverse-string-ii/。有点卡住了,不知道怎么用swap对前k个进行反转。求助卡哥字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili,看完了发现是用了上一题的reverse函数新学一个库函数reverse

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

下面是自己设计reverse函数的代码。

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

一道妙题。

第三题是替换数字https://kamacoder.com/problempage.php?pid=1064,对字符串大小扩容没把握好。看了卡哥的思路代码随想录,没想到竟然还用了双指针法。先扩容,从后往前填充。道高一尺,魔高一丈啊。

#include 
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() + count*5);
        int snewsize = s.size();
        for(int i = snewsize -1, j = soldsize - 1;j < i;i--, j--){
            if(s[j] > '9'||s[j] < '0'){
                s[i] = s[j];
            }
            else{
                s[i] = 'r';
                s[i - 1] = 'e';
                s[i - 2] = 'b';
                s[i - 3] = 'm';
                s[i - 4] = 'u';
                s[i - 5] = 'n';
                i -= 5;
            }
        }
        cout << s <

学到了字符串如何填充替换,这道题的双指针运用确实隐晦。

第四题是翻转字符串里的单词https://leetcode.cn/problems/reverse-words-in-a-string/,又是一道中等题。没啥想法,找卡哥代码随想录。有迭代的思想,先翻转整体,在对各个单词进行翻转。

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

去除空格时巧妙利用了数组中双指针去除元素的逻辑。

第五题是右旋字符串https://kamacoder.com/problempage.php?pid=1065,召唤卡哥代码随想录。先把两部分倒叙输出,再分别对子串翻转。代码很简洁,很美。

#include 
#include //妙啊
using namespace std;
int main(){
    int n;
    cin >> n;
    string s;
    cin >> s;
    int len = s.size();
    reverse(s.begin(), s.end());
    reverse(s.begin(), s.begin() + n);
    reverse(s.begin() + n, s.end());
    std::cout << s << std::endl;
    
}

或者也可以先翻转子串,再翻转整体。

#include 
#include 
using namespace std;
int main(){
    int n;
    cin >> n;
    string s;
    cin >> s;
    int len = s.size();
    reverse(s.begin(), s.begin() + len - n);
    reverse(s.begin() + len - n, s.end());
    reverse(s.begin(), s.end());
    std::cout << s << std::endl;
    
}

连做5道题,花了3个小时不得不说,代码跑出来的那一刻还是很开心的哈哈,最大的收获是对字符串的反转理解更深了,希望赶紧进入栈和队列。

你可能感兴趣的:(leetcode)