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

本文介绍了五个关于字符串操作的编程问题,包括反转整个字符串、间隔反转字符串、替换空格、反转单词以及左旋转字符串。每个问题都提供了相应的解题思路和简洁的C++代码实现,主要涉及字符串的遍历、反转和截取技巧。

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

344. 反转字符串

题目链接:344. 反转字符串,难度:简单
【实现代码】

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

【解题思路】

将前半部分的字符和后半部分的字符进行互换即可。

541. 反转字符串 II

题目链接:541. 反转字符串 II,难度:简单
【实现代码】

class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) {
            // 1. 每隔 2k 个字符的前 k 个字符进行反转
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= s.size()) {
                reverse(s.begin() + i, s.begin() + i + k );
            } else {
                // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
                reverse(s.begin() + i, s.end());
            }
        }
        return s;
    }
};

【解题思路】

在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。

剑指 Offer 05. 替换空格

题目链接:剑指 Offer 05. 替换空格,难度:简单
【实现代码】

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0;
        int oldSize = s.size();
        for (int i = 0; i < oldSize; i++) {
            if (s[i] == ' ') {
                count++;
            }
        }
        s.resize(s.size() + 2 * count);
        int newSize = s.size();
        for (int i = newSize - 1, j = oldSize - 1; i > j; j--) {
            if (s[j] != ' ') {
                s[i--] = s[j];
            } else {
                s[i--] = '0';
                s[i--] = '2';
                s[i--] = '%';
            }            
        }
        return s;
    }
};

【解题思路】

  1. 可以使用一个新的字符串存储。
  2. 可以不使用新的字符串,使用双指针法实现。
  3. 首先计算字符串中的空格数量,使用resize函数申请一个新的空间存储扩充后的字符串;
  4. 从后向前,fast指向字符串的末尾,slow指向新字符串的末尾,进行字符填充。

151. 反转字符串中的单词

题目链接:151. 反转字符串中的单词,难度:中等
【实现代码】

class Solution {
public:
    string reverseWords(string s) {
        int fast = 0;
        int slow = 0;
        for (; 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);
        
        reverse(s.begin(), s.end());
        int pos = s.size();
        for (int i = s.size() - 1; i >= 0; i--) {
            if (s[i] == ' ') {
                reverse(s.begin() + i + 1, s.begin() + pos);
                pos = i;
            }
            if (i == 0) {
                reverse(s.begin(), s.begin() + pos);
            }
        }
        return s;
    }
};

【解题思路】

  1. 难点在于如何消除多余的空格,起初我的想法是见到空格就使用erase删除一个,没有考虑到这样的时间复杂度是O(n^2)的。
  2. 使用双指针来自消除空格是巧妙的,类似于27. 移除元素,只是该元素是空格,而且需要考虑到单词与单词之间的空格。
  3. 消除完空格后,进行单词反转。如果直接进行单词反转,还要使用额外的空间。
  4. 所以先将字符串整体反转,再进行单个单词的反转,但需要注意最后一个单词,因为最后一个单词没有空格分隔。(我是从后向前就行反转的)

剑指 Offer 58 - II. 左旋转字符串

题目链接:剑指 Offer 58 - II. 左旋转字符串,难度:简单
【实现代码】

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(), s.begin() + n);
        reverse(s.begin() + n, s.end());
        reverse(s.begin(), s.end());
        return s;
    }
};

【解题思路】

先对前n个字符反转,再反转后面的字符,最后整体反转。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值