• 1.【刷爆LeetCode】替换空格(多方法、多思路解决)


            大家好我是Liyuyue!

            接下来我会讲我刷的LeetCode好题用到的好思路、好方法分享给大家一起学习,如果大家在看的过程中还有好的方法,可以评论区或者直接找我继续讨论,感谢大家的支持~!


    我们先来看要求:

    简要分析:

             也就是说当我们遇见 '空格' 的时候要将这个空格替换成 "%20" ,如果不是空格就正常拷贝,而且需要对s开辟多出来的空间。

            大体的思路分析完了,接下来我会讲三种方法解决这个问题,两个是用纯C语言去写,一种用C++去写。

    方法一:

    分析:

            先数出有多少个空格,因为每一个空格会替换成 "%20" 这三个字符,所以当我们数出有几个空格,也就知道了替换完后总共有多少个有效字符,还要注意要多开辟出来一个空间用来存放 '\0' 。分析完毕,接下来我画图给大家展示过程:

            当我们面对非空格时正常拷贝:

     

             当面对空格的时候我们要在start1连续添加 "%20",然后start1++、start2++。

     

             后面的操作也是如此。

             到这里后要将上面的 '\0' 一起拷贝下来,否则就会出现堆溢出的情况!这个比较特殊,要注意它们的下标。当拷贝完 len 这个下标后再结束。

            然后我们看下C语言给的模板:

            接下来我们将思路转换为代码(里面写的很清楚,大家仔细观看)。

    1. char* replaceSpace(char* s) {
    2. //有多少空格
    3. int spacecnt = 0;// 空格数
    4. char* ptr = s;
    5. int len = 0;// s 的长度
    6. while (*ptr)// 遍历一遍看有多少个
    7. {
    8. if (*ptr == ' ')
    9. spacecnt++;
    10. ptr++;
    11. len++;
    12. }
    13. int newlen = len + 2 * spacecnt;// 要开辟的空间有多少个有效字符
    14. char* tmp = (char*)malloc(sizeof(char) * newlen + 1);// 要多开辟出来一个留给'\0'
    15. int start1 = 0;
    16. int start2 = 0;
    17. while (start2 <= len)// 当start2 打印完len处的'\0'才停止
    18. {
    19. if (s[start2] != ' ')// 如果不为空格正常打印
    20. {
    21. tmp[start1++] = s[start2++];
    22. }
    23. else// 如果为空格就打印三个字符,两者都++
    24. {
    25. tmp[start1++] = '%';
    26. tmp[start1++] = '2';
    27. tmp[start1++] = '0';
    28. start2++;
    29. }
    30. }
    31. return tmp;// 返回新开辟空间的首地址
    32. }

    方法二:

            因为上一个方法是开辟空间后,将题目给的数组依次拷贝到开辟的空间中,遇到空格就打印 "%20",这里的方法是在一个空间内实现将空格转换为 '%20' ,上一个方法的空间复杂度是O(n),虽然这个方法的空间复杂度也是O(n),但是如果给的空间足够大的话,可以完成空间复杂度为O(1),所以这个方法也是很有必要的!

    分析:

            这里也需要找出开始 s 的有效字符的个数和开辟空间 tmp 有效字符的个数,但是这里要从最后开始往前进行遍历,因为是从后往前遍历,所以当遇到空格的时候要转换为 "02%" ,然后遍历停止的条件也会发生变化。

            先将 s 拷贝到新开辟的一个空间中(开辟空间的方法跟方法一是相同的)。

            然后开始从开辟好的空间的最后一个位置end1 拷贝到原来s 的 '\0' end2处。

            当遇到空格的时候,end1 一直往前走三个符号位分别输入 "02%" 。

            最后停止的条件是end2 和end1 相遇的时候(因为相遇就代表相遇的位置之前没有空格了)

            接下来我们将思路转换为代码(里面写的很清楚,大家仔细观看)。

    1. char* replaceSpace(char* s) {
    2. // 有多少空格
    3. int spacecnt = 0;// 空格个数
    4. char* ptr = s;
    5. int len = 0;// 有效字符个数
    6. while (*ptr)// 遍历一遍看有多少个
    7. {
    8. if (*ptr == ' ')
    9. spacecnt++;
    10. ptr++;
    11. len++;
    12. }
    13. int newlen = len + 2 * spacecnt;
    14. char* tmp = (char*)malloc(sizeof(char) * newlen + 1);// 多开辟一个'\0' 空间
    15. tmp[newlen] = '\0'; // 我这里直接手动给的'\0'
    16. strcpy(tmp, s);// 拷贝下来(模拟空间复杂度为O(1))
    17. int end1 = len - 1;
    18. int end2 = newlen - 1;
    19. while (end1 != end2)// 让end1 == end2 的时候停下来
    20. {
    21. if (tmp[end1] != ' ')// 不是空格正常遍历
    22. {
    23. tmp[end2--] = tmp[end1--];
    24. }
    25. else// 是空格给三个字符
    26. {
    27. tmp[end2--] = '0';
    28. tmp[end2--] = '2';
    29. tmp[end2--] = '%';
    30. end1--;
    31. }
    32. }
    33. return tmp;// 返回开辟的空间首地址
    34. }

    方法三:

            我们先看下C++给的模板是什么样的。

     

            这里是C++用库函数的方法,思路和方法一的方法一摸一样,大家直接看看代码,我继续给大家标记一下。

    1. class Solution {
    2. public:
    3. string replaceSpace(string s) {
    4. string str;// 创建一个对象
    5. for(auto ch : s)// 利用迭代器依次遍历s
    6. {
    7. if(ch != ' ')// 如果不是空格就拷贝
    8. str += ch;
    9. else// 是空格就拷贝"%20"
    10. str += "%20";
    11. }
    12. return str;// 返回
    13. }
    14. };

            这样就完成了,是不是非常简单。但是这里的效率不是很高,因为在 += 的时候会有增容的消耗,我们可以提前开好空间:

    1. class Solution {
    2. public:
    3. string replaceSpace(string s) {
    4. int spacecnt = 0;
    5. for(auto ch : s)
    6. {
    7. if(ch == ' ')
    8. ++spacecnt;
    9. }
    10. string str;
    11. // 提前开好空间,避免 += 增容的消耗,
    12. str.reserve(s.size() + spacecnt * 2);
    13. for(auto ch : s)
    14. {
    15. if(ch != ' ')
    16. str += ch;
    17. else
    18. str += "%20";
    19. }
    20. return str;
    21. }
    22. };

             如上就是 替换空格 的解析,接下来本专辑会持续更新【刷爆LeetCode】,和大家一起爆扣LeetCode!!!,如果大家喜欢看此文章并且有收获,可以时刻关注我,本专栏持续更新!

            感谢大家观看,感谢大家支持!

  • 相关阅读:
    猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库
    2022高处安装、维护、拆除考试练习题及答案
    phpcms打开后台首页时向官网发送升级请求觉得卡怎么办?
    深度学习基础之梯度下降
    不要小看一个Redis,从头到尾全是精华,阿里Redis速成笔记太香了
    【漏洞复现】短视频矩阵营销系统 ajax_uplaod接口处存在任意文件上传
    地图上必须要有指北针吗?
    数据库迁移-国产化-Oracle迁移至GBase8a(谓词)
    统计能整除数字的位数
    实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)
  • 原文地址:https://blog.csdn.net/weixin_69725192/article/details/125463517