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

344. 反转字符串

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

文章讲解:代码随想录

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size()-1;
        while(left<right){
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;
        }
    }
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

可以直接用swap交换

541. 反转字符串II

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

文章讲解:代码随想录

class Solution {
public:
    string reverseStr(string s, int k) {
        int left, right;
        int count = s.size()/(k*2);
        for(int c = count; c>0; c--){
            left = (c-1)*(k*2);
            right = left+k-1;
            while(left<right){
                swap(s[left],s[right]);
                left++;
                right--;
            }
        }
        int rest = s.size()%(k*2); 
        left = count*(k*2);
        if(rest<k){
            right = s.size()-1;
        }
        else{
            right = left+k-1;
        }
        while(left<right){
            swap(s[left],s[right]);
            left++;
            right--;
        }
        return s;
    }
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

剑指Offer 05.替换空格

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

【无视频讲解】

文章链接:代码随想录

【思路】

首先扩充数组到每个空格替换成"%20"之后的大小。

然后从后向前替换空格,也就是双指针法,过程如下:

i指向新长度的末尾,j指向旧长度的末尾

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0; // 统计空格的个数
        int sOldSize = s.size();
        for(int i=0; i<sOldSize; i++){
            if(s[i]==' '){
                count++;
            }
        }
        // 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
        s.resize(s.size()+count*2);  // %20有三个字符,比空格多了两个字符
        int sNewSize = s.size();
        // 从后向前将空格替换为"%20"
        for(int i=sNewSize-1,j=sOldSize-1; j<i; i--,j--){
            if(s[j]!=' '){
                s[i] = s[j];
            }
            else{
                s[i] = '0';
                s[i-1] = '2';
                s[i-2] = '%';
                i -= 2;
            }
        }
        return s;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

151. 翻转字符串里的单词

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

文章讲解:代码随想录

【解题思路】

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转
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]);
        }
    }

    string reverseWords(string s) {
        int slow = 0;
        for(int fast=0; fast<s.size(); fast++){
            if(s[fast]!=' '){
                if(slow!=0){
                    s[slow++] = ' ';
                }
                while(fast<s.size() && s[fast]!=' '){
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                }
            }
        }
        s.resize(slow);
        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; //更新下一个单词的开始下标start
            }
        }
        return s;
    }
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

剑指Offer58-II.左旋转字符串

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

【无视频讲解】

文章链接:代码随想录

为了让本题更有意义,提升一下本题难度:不能申请额外空间,只能在本串上操作

这道题目依然可以通过局部反转+整体反转 达到左旋转的目的。

具体步骤为:

  1. 反转区间为前n的子串
  2. 反转区间为n到末尾的子串
  3. 反转整个字符串

最后就可以达到左旋n的目的,而不用定义新的字符串,完全在本串上操作。

class Solution {
public:
    string reverse(string s, int begin, int end){
        while(begin<end){
            swap(s[begin++], s[end--]);
        }
        return s;
    }
    string reverseLeftWords(string s, int n) {
        // 反转前n个字符
        s = reverse(s, 0, n-1);
        // 反转剩余的字符
        s = reverse(s, n, s.size()-1);
        // 反转字符串
        s = reverse(s, 0, s.size()-1);
        return s;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值