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

发布时间 2023-09-14 14:10:48作者: zz子木zz

344.反转字符串

mydemo--(一次就过)--(成功)

class Solution {
public:
    void reverseString(vector<char>& s) {
        int len = s.size();
        char tmp;
        int i=0;
        int j = len-1;

        while(i<j)
        {
            tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
            i++;
            j--;
        }
    }
};

卡哥代码

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

541.反转字符串Ⅱ

mydemo--(自己思路)--(失败)

报错:超出时间限制

判断写的太复杂,而且 i是一个一个的跳,太慢了,会超时。

class Solution {
public:
    string reverseStr(string s, int k) {
        
        int i = 0;
        int j = 1;
        int len = s.size();

        while(1)
        {
            if(j-i+1 == 2*k)
            {
                reverse(s, i, i+k-1);
            
                if(j == len-1)  break;
            
                i = j+1;
                j = i+1;
                continue;
            }
            if(j-i+1 < k && j ==len-1)
            {
                reverse(s,i,j);
                break;
            }
            if(j-i+1 <2*k && j == len-1)
            {
                reverse(s,i,i+k-1);
                break;
            }
            
            i++	//一个一个跳,太慢了
        }
        return s;
    }

    void reverse(string& s, int i, int j)
    {
        while(i < j)
        {
            swap(s[i], s[j]);
            i++;
            j--;
        }
    }

};

卡哥代码

卡哥真言:

当操作字符串或者操作数组的时候,如果需要成段成段的处理,那么 i 就可以成段成段的跳,速度会快很多。

class Solution {
public:
    string reverseStr(string s, int k) {
    
    int len = s.size();

    for(int i=0; i<len; i+=2*k)
    {
      if(i+k <= len)
      {
        reverse(s.begin()+i, s.begin()+i+k);  //库函数实现的reverse是左闭右开的
        continue;
      }
      reverse(s.begin()+i, s.end());
    }
    return s;
    }
};

剑指Offer 05.替换空格

mydemo--(自己思路)--(失败)

我的思路肯定是没问题的,只是写法上有瑕疵

注意

C++中单引号表示字符,双引号表示字符串

卡哥demo

又是一道双指针的题。

当对连续序列(数组、字符串)等进行删除替换操作时,有前向法和后向法:

  1. 前向法:

在原序列上定义一个指针,当碰到要删除或者要替换的单位时,进行操作,同时,会对后面的单位进行处理,所以总的时间复杂度会是O(n^2)

  1. 后向法

在原序列上进行扩充,然后定义两个指针进行操作。这样做有两个好处:

  • 不用申请新数组。
  • 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
class Solution {
public:
    string replaceSpace(string s) {

        int count = 0;
        int sOldSize = s.size();
        for(int i=0; i <s.size(); i++)
        {
            if(s[i] == ' ')
            {
                count++;
            }
        }

        s.resize(s.size() + count*2);   //key
        int sNewSize = s.size();
        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;
    }
};

151.反转字符串中的单词

卡哥demo

双指针法,原地修改

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]);
    }

    void removeExtraSpaces(string& s)
    {
        int slow = 0;
        for(int fast = 0; fast < s.size(); fast++)
        {
            if(s[fast] != ' ')
            {   
                if(slow !=0)
                {
                    s[slow] = ' ';
                    slow++;
                }

                while(fast < s.size() && s[fast] != ' ')
                {
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                }
            }
        }
        s.resize(slow);
    }

    string reverseWords(string s) 
    {
        removeExtraSpaces(s);
        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;
            }
        }
        return s;
    }
};

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

卡哥demo

注意,库函数的 reverse( ) 是左闭右开

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;
    }
};