题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
当看到这个题时,我的第一个反应就是创建一个新的数组,大小刚好是原来数组的长度加上空格数*3。
- 先创建新数组
- 然后将字符串一个字符一个字符拷贝
- 当遇到空格则添加为%20,然后继续拷贝
- 重复以上过程,直到字符串结束
但是,如果题目不让你创建新的空间怎么办?
你可能会说,没事,我还有一种方法,就是从头到尾遍历一遍。
- 从头到尾遍历一遍
- 当遇到空格,我就把后边的字符都统统往后挪两个
- 然后将空格处替换成%20
- 重复以上步骤
这样也是没有创建新的空间,但是这样的时间复杂度是O(n^2)
接下来我来说一个时间复杂度为O(n)的方法,但是前提是原来的空间要足够。
- 我们可以先遍历一次字符串,这样就可以统计出字符串空格的总数,并可以由此计算出替换之后的字符串的总长度。
- 我们从字符串的尾部开始复制和替换。
- 首先准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。
- 然后我们向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。
- 碰到第一个空格之后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也要把P2向前移动3格。
- 重复上述步骤
接下来,就用代码来实现一下:
class Solution {
public:
void replaceSpace(char *str,int length) {
if(str == NULL && length <= 0){
return;
}
/*rellen为字符串str的实际长度*/
int rellen = 0; //原始长度
int blank = 0; //空格数
int i;
while(str[i++] != '\0'){ //遍历字符串
++rellen; //长度+1
if(str[i] == ' '){
++blank; //遇到空格+1
}
}
/*new_length为把空格替换成'%20'之后的长度*/
int newlen = rellen + 2 * blank;
int index_old = rellen; //原始字符串末尾索引值
int index_new = newlen; //计算长度后的字符串末尾索引值
/*index_old指针开始向前移动,如果遇到空格,替换成'%20',否则进行复制操作*/
while(index_old >= 0 && index_new > index_old){
if(str[index_old] == ' '){
str[index_new--] = '0';
str[index_new--] = '2';
str[index_new--] = '%';
}
else{
str[index_new--] = str[index_old];
}
--index_old;
}
}
};