题目4:替换空格(leetcodek连接:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/)
题目分析
如果题目要求不能在原字符串上进行修改(原字符串为常量不能进行修改、原字符串没有足够的空间),我们可以统计出字符串的长度和字符串中空格的数量,每替换一个空格,需要额外2个字节的空间,通过此规律我们可以开辟出一个足够大的空间,并赋值即可(这种方法比较简单不做详细解释)。
如果题目要求必须在原字符串上进行修改且时间复杂度为O(n)。我们先来看一下时间复杂度为O(n^2)的算法思路,顺序遍历字符串,遇到空格就将空格之后的字符后移2个字符,然后再将字符串替换成‘%20’,那么时间复杂度为O(n)的算法我们可以考虑从后向前遍历字符串,具体思路如下:
先遍历一遍字符串,统计出字符串的长度和字符串中空格的数量number,从后向前遍历字符串且将字符后移number个字符,遇到空格后让number-2同时另一个指针指向当前空格位置向后2个字符的为并从该位置开始替换成‘%20’,继续遍历字符串重复这个过程。
代码描述
char* replaceSpace(char* s,int length)
{
//参数中,length为数组空间大小
if (s == NULL)
return NULL;
//遍历字符串,统计空格数量number
char* str = s;
int number = 0;
while (*str)
{
if (*str == ' ')
number++;
str++;
}
//一个空格需要替换成3个字符,需要2个额外空间
number *= 2;
//如果所给数组空间不够,退出
if (strlen(s) + 1 + number > length)
return NULL;
//从后向前遍历字符串,遇到一次空格就进行一次替换并且number-2
while (str >= s)
{
if (*str != ' ')
{
*(str + number) = *str;
str--;
}
else
{
number -= 2;
//遇到空格,向空格后的number-2位置开始插入%20
char* q = str + number;
*q = '%';
*(q + 1) = '2';
*(q + 2) = '0';
str--;
}
}
return s;
}
//官方代码
/*length为字符数组string的总容量*/
void ReplaceBlank (char string [], int length)
{
if (string ==NULL & & length<=0)
return;
/ *originalLength为字符串string的实际长度*/int originalLength = 0;
int numberOfBlank = 0 ;int i = 0 ;
while (string [ i] != '\0 ')
{
++originalLength;
if(string[i] == ' ')
++nunberOfBlank ;
++i;
}
/*newLength为把空格替换成'%20'之后的长度*/
int newLength = originalLength + numberOfBlank * 2;
if (newLength > length)
return;
int indexOfOriginal = originalLength;int indexOfNew = newLength;
while (indexOforiginal >=0 && indexOfNew > indexoforiginal)
{
if(string [indexoforiginal] -= ' ')
{
string [indexofNew--] = '0';
string [ indexofNew --]= '2';
string [ indexOfNew --]= '%';
}
else
{
string [indexOfNew --] = string [indexOforiginal];
}
-- indexoforiginal;
}
}