字符串专题-LeetCode:反转字符串||、剑指Offer 05.替换空格、反转字符里的单词 代码思路和注意点

一、541. 反转字符串II

在这里插入图片描述

class Solution {
public:
    string reverseStr(string s, int k) {
        //先找区间 注意区间处理
        for(int i=0;i<s.size();i+=(2*k))
        {
            if(i+k<=s.size())
            {
                reverse(s.begin()+i, s.begin()+i+k);
            }
            else
            {
                reverse(s.begin()+i, s.end());
            }
        }
        return s;
    }
};

注意点: 这里很巧妙的是,区间的处理,让i以两倍的k来遍历,相当于每2k个长度处理一次

二、剑指 Offer 05. 替换空格

在这里插入图片描述

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0;//统计空格的个数
        int oldSize = s.size();//原字符串长度

        //统计空格个数
        for(int i=0;i<oldSize;i++) 
        {
            if(s[i]==' ') count++;
        }

        //扩展大小
        s.resize(oldSize+count*2);

        //插入字符
        int newSize = s.size();
        for(int i=oldSize-1,j=newSize-1;i<j;i--,j--)
        {
            if(s[i]!=' ')
            {
                s[j]=s[i];
            }
            else
            {
                s[j] = '0';
                s[j-1] = '2';
                s[j-2] = '%';
                j -=2;//跳过添加字符的位置 才能和i对应上
            }
        }
    return s;
    }
};

注意点:

  1. 要统计空格的个数,count;原字符串的大小oldSize
  2. 根据空格的个数,扩展原字符串的大小。%20占三个字符,空格本来占有一个,因此要增加 (3-1)×count ,新字符串大小为,newSize = oldSize+2×count
  3. 两个指针从后开始遍历, i=oldSize-1,j=newSize-1,i是改变大小前字符所在原位置,j是改变大小后字符所在的新位置
  4. 如果i位置不是空格,就把该位置的字符放到j位置;如果i位置的字符是空格,就从j、j-1、j-2三个位置分别插入0、2、%,此时j需要往前走两步,才可以和i同步,否则会错位。

三、151.翻转字符串里的单词

在这里插入图片描述

思路:
1、删除多余的空格
2、反转整个字符串
3、反转单词

1、删除多余的空格
可以参考LeetCode 27.移除元素的思路,就是找到空格进行删除,再单词前移并补充空格

//1、删除多余的空格
void removeExtraSpace(string& s)
{
    int slow = 0;//用来控制在单词后添加空格
    for(int i=0;i<s.size();i++)
    {
        if(s[i]!=' ')//不是空格就处理  删除所有空格
        {
            if(slow!=0) s[slow++] = ' ';//给单词之间加空格
            while(i<s.size() && s[i]!=' ')
            {
                s[slow++]=s[i++];//把整个单词前移
            }
        }
    }
    s.resize(slow);//slow的大小即为去除多余空格后的大小。
}

解释:
slow——用来控制在单词后添加空格,同时也记录了处理后字符串的长度,慢指针
i——这里相当于快指针
s[slow++]=s[i];——先赋值,slow再偏移
如果是i++ 最后一个单词没有反转

代码说明:

  1. 首先,从字符串头部开始遍历,如果不是空格就开始处理,也就是删除空格:
  2. 然后,判断此时慢指针所指的位置是不是第一个单词,如果不是第一个单词就添加空格,相当于此时已经把第一个单词已经整体向前移动了,需要在slow的下一个位置,即slow++的位置添加一个空格。
  3. 接着,继续通过slow来把下一个单词往前移动
  4. 最后,更新一下删除多余空格的字符串大小

2、反转整个字符串
可以参考LeetCode 344.反转字符串,可以自己写swap实现体,也可以调用swap函数,还可以调用reverse。上面的544也提到,不赘诉

//2、反转整个字符串
void reverseStr(string& s, int start, int end)
{
    for(int i=start,j=end;i<j;i++, j--)
    {
        swap(s[i], s[j]);
    }
}

3、反转单词

//3、反转单词
string reverseWords(string s) 
{
   removeExtraSpace(s);
   reverseStr(s, 0, s.size()-1);

   int start=0;
   for(int i=0;i<=s.size();i++)//要取等号
   {
       if(s[i]==' ' || i==s.size())
       {
           reverseStr(s,start,i-1);
           start=i+1;
       }
   }
   return s;
}

方法: 每找到一个单词就反转这个单词,可以调用reverse
要求: 用reverse的话,需要找到字符串的起始位置,即反转的长度

代码思路

  1. 从头开始遍历s,用一个变量start来表示开始的位置,即 int start=0;。removeExtraSpaces,删除了多余的空格后,字符串s第一个单词的开始下标一定是0。
  2. for循环找空格并反转单词,当s[i]==' ';时,表示找到了一个空格的位置,那么就反转这一小段的字符串。那么反转的的长度就是start~i-1这个范围
  3. 继续寻找下一个单词的长度,那么start要更新为第一个空格的下一个位置,也就是第二个单词开始的位置,然后再重复以上过程。

注意:
for循环如果不取等号i<s.size(),并且i==s.size()-1,最后一个单词的首字母没有反转,即het
for循环如果不取等号i<s.size(),并且i==s.size(),最后一个单词没有反转,即eht
for循环如果取等号i<=s.size(),但i==s.size()-1,最后一个单词的首字母没有反转,即het

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值