替换空格
题目:
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
解题思路:
(1)我们首先会想到从前往后遍历,遇见空格的时候就替换,但是这样1个字符替换成3个字符,我们必须将空格后面的所有字符往后移动两个字节,否则就有两个字符被覆盖,不建议这样的做法,这样一来时间复杂度为O(N^2),效率特别低。
(2)我们可以采用从后往前遍历,一次性将需要增加的字节空间开辟出来,依次挪动替换,具体操作如下:
首先,先遍历一次字符串,统计出字符串中空格的个数,来计算替换之后字符串的总长度。(替换之后的字符串长度=原来的长度+2*空格数,这里是2*空格数,是因为原来的空格已经占有了一个长度,只需要在原来的基础上再增加两个长度就可以将%20插入进去)
然后,从字符串的后面开始复制和替换。准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。
P1向前移动,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。
碰到空格之后,P1向前移动1格,在P2之前插入字符串”%20”,由于”%20”的长度为3,所以P2也要向前移动3格。
P1和P2的不断重复上述操作,直到P1和P2指向同一位置(此时所有的空格已经全部替换了)。
按照这样的思路,所有的字符都只复制(移动)了一次,由此这个算法的时间复杂度为O(n)。
牛客网上要求代码:
class Solution {
public:
void replaceSpace(char *str,int length) {
int count=0;
for(int i=0;i<length;i++){
if(str[i]==' ')
count++;
}
for(int i=length-1;i>=0;i--){
if(str[i]!=' '){
str[i+2*count]=str[i];
}
else{
count--;
str[i+2*count]='%';
str[i+2*count+1]='2';
str[i+2*count+2]='0';
}
}
}
};
public class Solution{
string ReplaceBlank(string str, int length)
{
// 先计算空格数 然后 再增容, 从后往前遍历,效率会比从前往后 快很多
if(length <= 0)
{
return str;
}
int numofblank = 0;
for (int i = 0; i < length; i++)
{
if(str[i] == ' ')
{
numofblank++;
}
}
str.resize(length+(numofblank<<2)); // 增容 并且将它初始化
int indexOfOldStr = length - 1;
int indexOfNewStr = length + (numofblank<<2) - 1;
for(int i = indexOfOldStr,j = indexOfNewStr; i >= 0; i--)
{
if(str[i] == ' ')
{
str[j] = '0';
str[j-1] = '2';
str[j-2] = '%';
j -= 3;
}
else
{
str[j--] = str[i];
}
}
return str;
}
};