代码随想录算法训练营第八天 | 字符串:整体反转+局部反转

文章介绍了如何使用C++进行字符串反转,包括基础操作和进阶技巧,如反转字符串、反转字符串内的子串,以及在限制条件下进行字符串操作。涉及到LeetCode的相关题目和解决方案,使用了双指针法来高效解决这些问题。

344

讲解视频:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili

文章讲解:代码随想录 (programmercarl.com)

状态:能直接做出。没难度。

代码

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

541

讲解视频:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili

文章讲解:代码随想录 (programmercarl.com)

状态:画图就可以看出,能直接做出,没难度。

代码

class Solution {
public:
    void reverse(string &s, int i, int j){	//将字符串s索引为i和j范围内字符翻转
        char tmp;
        while(i < j){
            tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
            ++i;
            --j;
        }
    }

    string reverseStr(string s, int k) {
        int len = s.size();
        for(int i = 0; i < len;){
            // 交换的部分,即前k个
            if(i + k > len){
                reverse(s, i, len - 1);
                break;
            }
            else{
                reverse(s, i, i + k - 1);
                i = i + k;
            }
			// 不交换的部分,即后k个
            if(i + k > len){
                break;
            }
            else{
                i = i + k;
            }
        }
        return s;
    }
};

剑指offer 05:双指针法

讲解视频:无

文章讲解:代码随想录 (programmercarl.com)

状态:瞄了一眼文章讲解的文字部分。然后就自己写出来了,理论上应该不能算做出来。

思路

  1. 先扫描一遍字符串s,记录空格的数量,然后在字符串s的基础上扩充内存,以存放变更后的全部字符。
  2. 双指针:指针j指向新数组尾部,往左边移动;指针i指向原数组尾部,向左移动:
    1. 若s[i] != 空格,则s[j]=s[i],且i–,j–;
    2. 若s[i] == 空格,则i–,s[j–]=‘0’,s[j–]=‘2’,s[j–]=‘%’;
    3. 注意:循环边界为i != -1。

代码

class Solution {
public:
    string replaceSpace(string s) {     //双指针法
        int space_nums = 0;
        for(int i = 0; i < s.size(); ++i){
            if(s[i] == ' ') ++space_nums;   //统计空格数目
        }
        int i = s.size() - 1;   //原数组尾部
        s.resize(s.size() + 2 * space_nums);    //扩充s的大小,以容纳变换后的所有字符

        // 双指针法:j指向新数组尾部;i遍历原数组,从s最后一个字符开始;
        int j = s.size() - 1;   //新数组尾部
        while(i != -1){
            if(s[i] != ' '){
                s[j] = s[i];
                --j;
                --i;
            }
            else{
                --i;
                s[j--] = '0';
                s[j--] = '2';
                s[j--] = '%';
            }
        }
        return s;
    }
};

151 快慢指针

讲解视频:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili

文章讲解:代码随想录 (programmercarl.com)

状态:看了题解方法,不看代码自己能写出来。不能算做出来。

思路(使用整体反转+局部反转来实现)

  1. 移除多余空格:用双指针
  2. 将整个字符串反转
  3. 将每个单词反转

剑指offer58

讲解视频:无

文章讲解:代码随想录 (programmercarl.com)

状态:做不出来。

提升一下本题难度:不能申请额外空间,只能在本串上操作

思路(与上一题相似,使用整体反转+局部反转来实现)

  1. 反转区间为前n的子串

  2. 反转区间为n到末尾的子串

  3. 反转整个字符串

    如下图所示

    在这里插入图片描述

代码

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(), s.begin() + n);  // 反转区间为前n的子串
        reverse(s.begin() + n, s.end());    // 反转区间为n到末尾的子串
        reverse(s.begin(), s.end());    // 反转整个字符串
        return s;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值