目录
1. 替换空格
1.1 题目描述
1.2 题目背景
1.3 必要的思考
1.4 思路一
1.5 思路二
1.6 思路三(学方法)
1.7 小试牛刀
1. 替换空格
原题链接:剑指 Offer 05. 替换空格 - 力扣(LeetCode)https://leetcode.cn/problems/ti-huan-kong-ge-lcof/submissions/
1.1 题目描述
给你一个字符串要求你把字符串中所有的空格换成%20。
1.2 题目背景
在网络编程中,如果URL参数中含有特殊字符,如空格,'#' 等,则可能导致服务器无法获得正确的参数值。我们就需要将这些特殊的符号转换成服务器可以识别的字符。转换的规则是在'%' 的后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换成 "%20" 。再比如 '#' 的ASCII码为35,即十六进制的0x23,它在URL中被替换成 "%23"。
1.3 必要的思考
看到该题目,我们首先应该想到的是原来一个空格字符串,替换之后长度必然会变长。如果是在原来的字符串上进行替换,就有可能覆盖修改在该字符串后面的内存。如果是创建新的字符串并在新的字符串上进行替换,我们可以给自己分配足够多的内存。由于这道题有两种不同的解决方案,首先我们应该明确LeetCode上的是哪一种!如果是在原来的字符串上进行替换,必须保证输入的字符串后面有足够多的空余内存。
我帮大家测试了,LeetCode上输入的字符串后面是没有多余的内存的。
这是LeetCode上典型的内存错误哈,本题就是越界访问了。
1.4 思路一
我们选择创建新的字符串,分配足够的空间
我们只需要遍历原来的字符串,是空格的话就追加 ''%20",不是空格就追加原字符串的内容。我就偷个懒,用C语言的库函数哈。
char* replaceSpace(char* s) {
assert(s);
char media[] = "%20";
char* ret = (char*)calloc(sizeof(char), 30000);
char* temp = s;
while (*temp != '\0')
{
if (*temp == ' ')
{
strncat(ret, media, 3); //是空格追加"%20"
}
else
{
strncat(ret, temp, 1); //不是空格追加原字符
}
temp++;
}
return ret;
}
1.5 思路二
我们假设输入的字符串后面有足够的空间,LeetCode上没有,可以开辟新的空间模拟输入的字符串后面有足够的空间,我嫌麻烦,就直接在Visual Studio 上演示啦。
我们遍历字符串,遇到一个空格,就将字符串后面的内容向后移动两个位置(因为一个空格被替换成 "%20" 多了两位嘛),直到遍历结束。
显然该解题方法时间复杂度为O(N*N),空间复杂度为O(1)。
下面以字符串 "We are happy." 举例分析。
char* replaceSpace(char* str)
{
assert(str);
char* temp = str;
while (*temp != '\0')
{
if (*temp == ' ')
{
int length = strlen(str);
char* end = str + length; //找到'\0'的位置
//字符后移2位
while (end > temp)
{
*(end + 2) = *end;
end--;
}
//空格替换为"%20"
*temp++ = '%';
*temp++ = '2';
*temp++ = '0';
continue;
}
temp++;
}
return str;
}
int main()
{
char str[1000];
printf("请输入字符串:");
gets(str);
printf("%s",replaceSpace(str));
return 0;
}
1.6 思路三(学方法)
我们先遍历一次字符串,这样就能统计出字符串中空格的个数,由此我们可以计算出替换之后字符串的总长度。一个空格被替换成 "%20" 就会在原字符串长度的基础上加二。我们维护两个指针p1,p2,让p1指向输入字符串的末尾 '\0' 的位置,让p2指向输出字符串的末尾的位置,计算方法:在p1的基础上加上 2 * 输入字符串中空格的个数。然后对*p1的值进行判断,如果*p1不是空格就把*p1的值给给*p2,p1减一,p2减一;如果是空格就让p1减一,p2填入 '0' 后减一,再填入 '2' 后减一,再填入 '%' 后减一,依次类推,直到p1和p2重合。重合就代表空格都被替换完毕。(最开始p1,p2相距 空格数 * 2 的距离,p1每次遇到一个空格,p1只会减一,而p2会减三,意味着在对空格数做减法,一旦空格数减完了,p1和p2自然就相遇了,程序也就该结束了。)
解题的时间复杂度O(N),空间复杂度O(1)。
下面以字符串 "We are happy." 举例分析一波:
char* replaceSpace(char* s)
{
assert(s);
char* temp = s;
int count = 0;
while (*temp != '\0')
{
if (*temp == ' ')
count++;
temp++;
}
int length = strlen(s);
char* p1 = s + length; //找p1的位置
char* p2 = p1 + 2 * count; //找p2的位置
while (p1 < p2)
{
//*p1为空格
if (*p1 == ' ')
{
p1--;
//赋值"%20"
*p2-- = '0';
*p2-- = '2';
*p2-- = '%';
}
else //*p1不为空格
{
*p2-- = *p1--;
}
}
return s;
}
int main()
{
char str[1000];
printf("请输入字符串:");
gets(str);
printf("%s",replaceSpace(str));
return 0;
}
1.7 小试牛刀
学了思路三的方法,宝们肯定能够拿捏这道题啦!!!
上链接:
力扣https://leetcode.cn/problems/merge-sorted-array/