代码随想录 day08

344.反转字符串

// 思路与双指针法类似
class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() - 1;
        
        while (left < right) {
            swap(s[left], s[right]);
            
            // 交换完成两个字符后,需要更新左右指针
            left++;
            right--;
        }
    }
};

541.反转字符串II

// 此题代码难度不大,但是理解逻辑较困难
class Solution {
public:
    // 实现反转字符串
    void myReverse(string& s, int left, int right) {
        while (left < right) {
            swap(s[left], s[right]);
            left++;
            right--;
        }
    }
    
    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()) {
                myReverse(s, i, i + k - 1);
                continue;
            }
            
            // 3. 剩余字符 < k 则剩余字符全部反转
            myReverse(s, i, s.size() - 1);
        }
        return s;
    }
};

剑指 offer 05.替换空格

class Solution {
public:
    string replaceSpace(string s) {
        int spaceCount = 0; // 记录字符串中的空格数量
        int oldSize = s.size(); // 记录原字符串的大于
        
        // 计算空格的数量
        for (int i = 0; i < s.size(); i++) {
            if (' ' == s[i]) {
                spaceCount++;
            }
        }

        // 根据空格的数量重新设置字符串的大小
        s.resize(s.size() + 2 * spaceCount);

        for (int i = s.size() - 1, j = oldSize - 1; j < i; i--, j--) {

            if (s[j] != ' ') { // 将原字符串中不为 ’ ‘ 的内容转移到新字符串中
                s[i] = s[j];
            } else { // 如果该位置的内容为 ’ ‘ 则替换为 %20
                s[i - 2] = '%';
                s[i - 1] = '2';
                s[i] = '0';
                i -= 2; // 特别注意:此处 i -= 2;
            }
        }
        return s;
    }
};

151.反转字符串中的单词

// 此题细节较多
// 思路:
// 首先删除字符串中多余的空格
// 之后反转整个字符串
// 最后反转每个单词
class Solution {
public:
    // 反转字符串
    void myReverse(string& s, int left, int right) {
        while (left < right) {
            swap(s[left], s[right]);
            left++;
            right--;
        }
    }

    // 删除字符串多余空格
    // 整体思路参考 27.移除元素
    // 快慢指针
    void removeExtraSpace(string& str) {
        int slow = 0;
        for (int fast = 0; fast < str.size(); fast++) {
            if (' ' != str[fast]) { // 遇到非空格进行处理
                if (0 != slow) { // 0 != slow 说明不是第一个单词,需要在单词后加上空格
                    str[slow++] = ' '; // 手动控制空格,为单词之间添加空格
                }

                // 补上空格,遇到空格,说明单词结束
                while (fast < str.size() && str[fast] != ' ') {
                    str[slow++] = str[fast++];
                }
            }
        }
        // 此处类比 27.移除元素 返回新数组的长度
        str.resize(slow);
    }

    string reverseWords(string s) {
        // 1. 删除多余的空格
        removeExtraSpace(s);
        // 2. 反转整个字符串
        myReverse(s, 0, s.size() - 1);
        // 3. 反转字符串中的单词
        int start = 0;
        // 注意:此处是 <=
        for (int i = 0; i <= s.size(); i++) {

            // 当出现空格或到达字符串结尾,说明一个单词结束
            if (' ' == s[i] || i == s.size()) {
                myReverse(s, start, i - 1);

                // 更新下一个单词的位置
                // 注意:i 下标的内容为空格
                start = i + 1;
            }
        }
        return s;
    }
};

剑指 offer 58-II 左旋转字符

// 思路:
// 1. 首先反转前 n 个字符
// 2. 之后反转 n 以后的字符
// 3. 最后反转整个字符串
class Solution {
public:
    void myReverse(string &str, int left, int right) {
        while (left < right) {
            swap(str[left], str[right]);
            left++;
            right--;
        }
    }

    string reverseLeftWords(string s, int n) {
        // 1. 反转前 n 个字符
        myReverse(s, 0, n - 1);
        // 2. 反转 n 之后的字符
        myReverse(s, n, s.size() - 1);
        // 3. 反转整个字符串
        myReverse(s, 0, s.size() - 1);

        return s;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值