目录
1. 替换空格
1.1 题目描述
1.2 题目背景
1.3 必要的思考
1.4 思路一
1.5 思路二
1.6 思路三(学方法)
1.7 小试牛刀
原题链接:剑指 Offer 05. 替换空格 - 力扣(LeetCode)
https://leetcode.cn/problems/ti-huan-kong-ge-lcof/submissions/
给你一个字符串要求你把字符串中所有的空格换成%20。
在网络编程中,如果URL参数中含有特殊字符,如空格,'#' 等,则可能导致服务器无法获得正确的参数值。我们就需要将这些特殊的符号转换成服务器可以识别的字符。转换的规则是在'%' 的后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换成 "%20" 。再比如 '#' 的ASCII码为35,即十六进制的0x23,它在URL中被替换成 "%23"。
看到该题目,我们首先应该想到的是原来一个空格字符串,替换之后长度必然会变长。如果是在原来的字符串上进行替换,就有可能覆盖修改在该字符串后面的内存。如果是创建新的字符串并在新的字符串上进行替换,我们可以给自己分配足够多的内存。由于这道题有两种不同的解决方案,首先我们应该明确LeetCode上的是哪一种!如果是在原来的字符串上进行替换,必须保证输入的字符串后面有足够多的空余内存。
我帮大家测试了,LeetCode上输入的字符串后面是没有多余的内存的。
这是LeetCode上典型的内存错误哈,本题就是越界访问了。
我们选择创建新的字符串,分配足够的空间
我们只需要遍历原来的字符串,是空格的话就追加 ''%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;
}
我们假设输入的字符串后面有足够的空间,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;
}
我们先遍历一次字符串,这样就能统计出字符串中空格的个数,由此我们可以计算出替换之后字符串的总长度。一个空格被替换成 "%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;
}
学了思路三的方法,宝们肯定能够拿捏这道题啦!!!
上链接:
力扣
https://leetcode.cn/problems/merge-sorted-array/