剑指offer----C语言版----第三天
创始人
2024-05-02 23:40:39
0

目录

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/

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...