训练营day08 字符串 | 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字

344.反转字符串

是否能用库函数?

如果题目的关键部分直接用库函数就可以解决,那建议不要使用库函数,如果库函数仅仅是解题过程中的一部分,且十分清楚内部原理的话,可以考虑使用库函数

代码

class Solution {
public:
    void reverseString(vector& s) {
        int first = 0;
        int last = s.size()-1;
        for(;first

541. 反转字符串II

代码

// 可以对字符串直接处理,不用转成数组
class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i=0; i s.size()-1){
                reverse(s.begin()+i, s.end());
            }
            // 否则翻转前k  注意第二项填的是下一个指针,即左闭右开
            else{
                reverse(s.begin()+i, s.begin()+i+k);
            }
        }
        return s;
    }
};

本题中,reverse不是关键,所以可以直接用库,库函数输入的是地址

如果要自己写reverse,如果写成左闭右闭,那输入时要记得-1

剑指Offer 05.替换空格

思路:

很多数组填充问题,都是预先给数组扩容填充后的大小,然后从后往前进行操作,两个好处

  • 不用申请新数组
  • 从后往前填充元素,避免从前往后填充时,每次添加元素都要在添加元素后的所有元素向后移动

具体步骤:

1-求空格数

2-扩充字符串,利用resize方法,扩充大小为空格数*2

3-快指针j和慢指针i,j从原字符串末尾开始,i从新字符串末尾开始,同时向左遍历,如果j遇到空格,则i填充0 2 %;如果j不是空格,则i填充与j相同的值

代码

class Solution {
public:
    string replaceSpace(string s) {
        // 求空格个数
        int count = 0;
        // for(int i=0; i

151.翻转字符串里的单词

思路

分三步走:

1-移除多余空格,只剩下单词中间的一个空格

2-进行翻转,可以利用reverse(),时间复杂度也是O(n) (因为这一步不是关键步骤,所以可以用库函数,如果要写可以参照上面第一题)

3-每个单词内进行翻转

本题重点是移除多余空格,如果使用库函数erase(),则时间复杂度为O(n^2) (因为是在遍历中erase,纯erase是O(n)),所以应用双指针法,为O(n)

双指针移除多余空格

快指针要遍历全部元素

如果快指针指向元素不为空,就要进入一个循环,让fast后面的一个单词赋给slow(即fast指向空或者到头时跳出循环)

但在单词赋值之前要判断一下,这个单词是否为第一个单词,如果不是第一个单词,就要给slow先赋空格,再从fast把单词搬过来

代码

class Solution {
public:
    // 注意自定义的两个函数传递的是地址
    // 翻转函数,要输入头和尾是方便后面单词的翻转
    void reverse(string& s, int begin, int end){
        for(int i=begin, j=end; i

包含三部分:翻转指定范围元素、去除多余空格(重点)、根据空格间隔翻转每个单词

在最后一部分中,巧妙的写法是i可以等于s.size(),这样把fast指向结尾的情况考虑进去,不用再分情况讨论

注意:自定义的两个函数传的是地址,不用return,而题目中给的函数是传入string类型返回string类型的,不是地址

剑指Offer58-II.左旋转字

思路:整体翻转+局部翻转的思路(实际为两个局部翻转,再整体翻转)

训练营day08 字符串 | 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字_第1张图片

 代码

class Solution {
public:
    void reverse(string& s, int begin, int end){
        for(int i=begin, j=end; i

总结

今日四道题都是反转问题。344 反转字符串是最简单,利用双指针;541 反转字符串Ⅱ加上条件,利用规律一段一段反转;151反转字符串中单词,先整体反转,再把每个单词反转回来(但这道题中最难的是去除多余空格-双指针法);最后一题左旋转字也是利用整体反转+局部反转

剩下一道替换空格,为先扩充数组,再利用双指针法,从后往前填充(如果从前往后会每次都让后面元素全部后移,时间复杂度O(n^2))

你可能感兴趣的:(代码随想录算法训练营,算法,leetcode)