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

344.反转字符串

链接:[344.反转字符串](https://leetcode.cn/problems/reverse-string/

思路

遍历前半部分元素和后半部分swap即可

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

541. 反转字符串II

链接:leetcode 541. 反转字符串II

思路

通过counter取余数的方式记录2k的步数周期,需要注意的是reverse函数在使用时的区间边界比较难确定,最好是使用具体的数据(基数还有偶数)来推演公式。

class Solution {
public:
    string reverseStr(string s, int k) {
        int counter = 0;
        for (int i = 0; i < s.size(); ++i){
            counter = (counter + 1) % (2 * k);
            if (counter == 0) {
                reverse(s, i - (2 * k - 1), i - k);
                continue;
            }
            if (i == s.size() - 1){
                if (counter <= k) reverse(s, i - (counter - 1),i);
                else reverse(s, i - (counter - 1), i - (counter - k));
            }
        }
        return s;
    }
    // reverse string at [i,j]
    void reverse(string &s, int i, int j){
        while(i < j) {
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            ++i;
            --j;
        }
    }
};

剑指Offer 05.替换空格

链接:剑指Offer 05.替换空格

思路

第一反应是使用正则表达式的replace直接进行替换,但实际上应该先通过计算空格数对对字符串进行扩充,然后遍历填入新的扩充字符串。

知识积累

c++的正则化replace:

std::regex pattern(匹配字符串);
string res = std::regex_replace(目标字符串, pattern, 替换字符串);
class Solution {
# include <regex>
public:
    string replaceSpace(string s) {
        // replace的用法
        std::regex regexPattern(" ");
        string res = std::regex_replace(s, regexPattern, "%20");
        return res;
    }
};

151.翻转字符串里的单词

链接:leetcode 151.翻转字符串里的单词

思路

通过双指针来定位单词,然后通过截取子串的方式获取单词字符串,最后通过字符串拼接的方式来得到最终结果。由于需要反转单词顺序,所以考虑从后往前遍历。同时这种双指针确定区间的方式,两指针需要停在不同的值上,这里我们让right停在非空格上,left停在空格上。需要注意left和right的初始化和更新方式,边界情况更是要格外小心。right初始为字符串尾部,通过while循环跳过空格,前导空格的情况下right会一直移动直至越界,此时已经遍历完所有单词,返回结果即可。left的初始化可以为right-1也可以为right,但其实为right考虑出发去移动会更稳妥点,可以少考虑一些边界情况。right的移动会把多空格和尾随空格都去处,假如没有前导空格,那么left的移动会越界。此时需要最后一个单词还没处理,单独处理最后一个单词并且返回结果。否则说明单词位于left+1~right的区间,对单词进行处理。之后要处理下一个单词需要对right进行更新:

            //非常容易遗漏
            right = left - 1;

忘记了就会导致死循环。right更新为left或left -1都可以。

class Solution {
public:
    string reverseWords(string s) {
        //前导空格,多空格,尾随空格
        string res = "";
        int right = s.size() - 1;
        int left;
        while (right >= 0) {
            while (s[right] == ' ') {
                right--;
                //前导空格
                if (right < 0) return res;
            }
            left = right;
            while (s[left] != ' '){
                left--;
                if (left < 0) {
                    res = extd_str(res, s, 0, right);
                    return res;
                }
            }
            res = extd_str(res, s, left + 1, right);
            //非常容易遗漏
            right = left - 1;
        }
        return res;
    }
    string extd_str(string res, string s, int start, int end) {
        if (res != "") {
            res += " ";
        }
        res += s.substr(start, end - start + 1);
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值