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

LeetCode 344.反转字符串

题目链接:LeetCode 344.反转字符串

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

思路:简单的双指针法。

小结:可以用swap函数代替上述过程。


LeetCode 541. 反转字符串II

题目链接:LeetCode 541. 反转字符串II

class Solution {
public:
    void reverse(string &s,int left,int right)
    {
        for(int i = left,j = right;i < j;i++,j--)
        swap(s[i],s[j]);
    }
    string reverseStr(string s, int k) {
        for(int i = 0; i < s.size();i += (2*k))
        {
            if(i + k <= s.size())
            {
                reverse(s,i,i + k - 1);
                continue;
            }
            reverse(s,i,s.size()- 1);
        }
        return s;
    }
};

思路:反转函数与上题一致,每次取2k段的字符,当剩余字符大于k时,则反转k个字符并向后移动2k段,否则就将其全部反转。

小结:因题目是以2k作为单位与判别标准,循环节移动时需移动2k个单位


LeetCode 剑指Offer 05.替换空格

题目链接:LeetCode 剑指 Offer 05. 替换空格

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0;
        int size_old = s.size();
        for(int i = 0;i < size_old;i++)
        {
            if(s[i] == ' ')
            {
                count++;
            }
        }
        s.resize(size_old + count * 2);
        int size_new = s.size();
        for(int i = size_new - 1,j = size_old - 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;
    }
};

思路:先统计原字符串的空格数,后扩充字符串长度,最后将空格替换为“%20”

小结:

1.不用申请新的数组。

2.从后往前填充可以避免从前往后移动填充需要将之后的字符往后移动


LeetCode 151.翻转字符串里的单词

题目链接:LeetCode 151.翻转字符串里的单词

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 removeSpace(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++];
                }//填充单词
            }
        }
        s.resize(slow);//调整字符串大小
    }
//删除多余空格函数
    string reverseWords(string s) {
      removeSpace(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;
    }
};

思路:通过双指针法找到空格位置,删除多余空格,并在每个单词之间保留一个空格,之后将整个字符串进行反转,再利用双指针法找空格,并将空格前的单词进行反转

小结:

1.题目中反转单词,寻找空格依靠双指针法完成。

2.反转区间为左闭右闭区间


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

题目链接:LeetCode 剑指Offer58-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个字符处分界分别将n之前和n之后的字符串进行反转最后整体反转即可。


版权声明:本文为m0_74294107原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。