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

也就是说当我们遇见 '空格' 的时候要将这个空格替换成 "%20" ,如果不是空格就正常拷贝,而且需要对s开辟多出来的空间。
大体的思路分析完了,接下来我会讲三种方法解决这个问题,两个是用纯C语言去写,一种用C++去写。
先数出有多少个空格,因为每一个空格会替换成 "%20" 这三个字符,所以当我们数出有几个空格,也就知道了替换完后总共有多少个有效字符,还要注意要多开辟出来一个空间用来存放 '\0' 。分析完毕,接下来我画图给大家展示过程:
当我们面对非空格时正常拷贝:
当面对空格的时候我们要在start1连续添加 "%20",然后start1++、start2++。
后面的操作也是如此。

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

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

接下来我们将思路转换为代码(里面写的很清楚,大家仔细观看)。
- char* replaceSpace(char* s) {
- //有多少空格
- int spacecnt = 0;// 空格数
- char* ptr = s;
- int len = 0;// s 的长度
- while (*ptr)// 遍历一遍看有多少个
- {
- if (*ptr == ' ')
- spacecnt++;
- ptr++;
- len++;
- }
- int newlen = len + 2 * spacecnt;// 要开辟的空间有多少个有效字符
- char* tmp = (char*)malloc(sizeof(char) * newlen + 1);// 要多开辟出来一个留给'\0'
- int start1 = 0;
- int start2 = 0;
- while (start2 <= len)// 当start2 打印完len处的'\0'才停止
- {
- if (s[start2] != ' ')// 如果不为空格正常打印
- {
- tmp[start1++] = s[start2++];
- }
- else// 如果为空格就打印三个字符,两者都++
- {
- tmp[start1++] = '%';
- tmp[start1++] = '2';
- tmp[start1++] = '0';
- start2++;
- }
- }
- return tmp;// 返回新开辟空间的首地址
- }
因为上一个方法是开辟空间后,将题目给的数组依次拷贝到开辟的空间中,遇到空格就打印 "%20",这里的方法是在一个空间内实现将空格转换为 '%20' ,上一个方法的空间复杂度是O(n),虽然这个方法的空间复杂度也是O(n),但是如果给的空间足够大的话,可以完成空间复杂度为O(1),所以这个方法也是很有必要的!
这里也需要找出开始 s 的有效字符的个数和开辟空间 tmp 有效字符的个数,但是这里要从最后开始往前进行遍历,因为是从后往前遍历,所以当遇到空格的时候要转换为 "02%" ,然后遍历停止的条件也会发生变化。
先将 s 拷贝到新开辟的一个空间中(开辟空间的方法跟方法一是相同的)。

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

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

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

接下来我们将思路转换为代码(里面写的很清楚,大家仔细观看)。
- char* replaceSpace(char* s) {
- // 有多少空格
- int spacecnt = 0;// 空格个数
- char* ptr = s;
- int len = 0;// 有效字符个数
- while (*ptr)// 遍历一遍看有多少个
- {
- if (*ptr == ' ')
- spacecnt++;
- ptr++;
- len++;
- }
- int newlen = len + 2 * spacecnt;
- char* tmp = (char*)malloc(sizeof(char) * newlen + 1);// 多开辟一个'\0' 空间
- tmp[newlen] = '\0'; // 我这里直接手动给的'\0'
- strcpy(tmp, s);// 拷贝下来(模拟空间复杂度为O(1))
- int end1 = len - 1;
- int end2 = newlen - 1;
- while (end1 != end2)// 让end1 == end2 的时候停下来
- {
- if (tmp[end1] != ' ')// 不是空格正常遍历
- {
- tmp[end2--] = tmp[end1--];
- }
- else// 是空格给三个字符
- {
- tmp[end2--] = '0';
- tmp[end2--] = '2';
- tmp[end2--] = '%';
- end1--;
- }
- }
- return tmp;// 返回开辟的空间首地址
- }
我们先看下C++给的模板是什么样的。
这里是C++用库函数的方法,思路和方法一的方法一摸一样,大家直接看看代码,我继续给大家标记一下。
- class Solution {
- public:
- string replaceSpace(string s) {
- string str;// 创建一个对象
- for(auto ch : s)// 利用迭代器依次遍历s
- {
- if(ch != ' ')// 如果不是空格就拷贝
- str += ch;
- else// 是空格就拷贝"%20"
- str += "%20";
- }
- return str;// 返回
- }
- };
这样就完成了,是不是非常简单。但是这里的效率不是很高,因为在 += 的时候会有增容的消耗,我们可以提前开好空间:
- class Solution {
- public:
- string replaceSpace(string s) {
- int spacecnt = 0;
- for(auto ch : s)
- {
- if(ch == ' ')
- ++spacecnt;
- }
- string str;
- // 提前开好空间,避免 += 增容的消耗,
- str.reserve(s.size() + spacecnt * 2);
- for(auto ch : s)
- {
- if(ch != ' ')
- str += ch;
- else
- str += "%20";
- }
- return str;
- }
- };
如上就是 替换空格 的解析,接下来本专辑会持续更新【刷爆LeetCode】,和大家一起爆扣LeetCode!!!,如果大家喜欢看此文章并且有收获,可以时刻关注我,本专栏持续更新!
感谢大家观看,感谢大家支持!