三、剑指 Offer 05. 替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
解题思路 :题目要求把把字符串中的空格替换为“%20”,这样字符串长度肯定会变化,但是JavaScript中的字符串是初始化之后就无法改变了,这样我们要么再创建一个新字符串,要么就采用把字符串转化为数组的形式进行原地更改(因为JavaScript数组的长度是可以改变的)。
第一种方法原地修改替换空格
解题思路 :这里我们采用字符串转换为数组的形式来解决问题。
需要我们解决的问题有:①计算替换之后的数组长度 ② 如何将空格对应的位置替换为“%20”。
①第一个问题,我们就可以使用for循环,找出空格个数,在对应转换需要的新字符串的个数。一个空格换一个“%20”,那么在原本空格有了一个位置的基础上,我们就需要在添加一个2个位置。
②第二个问题,新旧字符串的长度我们都已经解决了,那么就应该考虑怎么把空格替换,因为我们就是在一个数组里面把空格替换为“%20”,那么如果我们使用for循环进行遍历,一遇到空格,就把他的位置和后面2个位置替换为“%20”,那么我们这样就肯定会把原来空格之后的字符给覆盖掉,那么我们就肯定不能进行成功的遍历出准确的新字符串了,毕竟要搬运的字符都被覆盖了,那还这么搬运到之后的位置。
思考: 既然从头开始遍历不行,那么我们就从数组末尾进行遍历。那为什么要这样做? 听我细细道来,首先,我们把原先的数组因为空格计算了多出来的长度,但是这些位置我们并没有放置新字符,也就是空的。而且不管空格在哪里,我们只要从末尾开始搬运字符,那么我们因为位置数数值不是空的该覆盖的时候,那么这个覆盖的值一定不是我们还没有搬运的字符,也就是我们可以保证还没有搬运的字符的“安全性”。 换句话来说,就是字符的搬运给“%20”,留出了新的空位置。
//原地修改替换空格 var replaceSpace = function(s) { s = s.split(''); let OldLen = s.length; let spaceCount = 0; for (let i = 0; i < OldLen; i++) { if(s[i] == ' ') spaceCount++; } s.length += spaceCount * 2; for(let i = OldLen-1, j = s.length - 1; i >=0;i--,j--) { if(s[i] !==' ') { s[j] = s[i]; } else { s[j] = '0'; s[j-1] = '2'; s[j-2] = '%'; j -= 2; } } return s.join(''); }; 复制代码
第二种方法 循环遍历
题解思路: 这就比较暴力了,字符串被写死了,就在创建一个新字符串,循环遍历旧字符串,一旦遇到空格,就往新字符串添加“%20”,其他情况就按部就班的搬运字符。
// 循环遍历 var replaceSpace = function(s) { let res = ''; for(let i = 0;i < s.length; i++) { const ch = s[i] if(ch === " ") { res += "%20" } else { res += ch; } } return res } 复制代码
var replaceSpace = function(s) { // 1. 调用库函数懒蛋法 正则匹配 s.replace return s.replace(/\s/g, '%20') // 2. 规规矩矩loop法 空格的unicode码值是32 let res = '' for (let c of s) res += c.charCodeAt() === 32 ? '%20' : c return res }; var replaceSpace = function(s) { return s.replaceAll(' ', '%20'); }; 复制代码
var replaceSpace = function(s) { s = s.split(''); for(let i=0;i<s.length;i++){ if(s[i] == ' '){ s[i] ='%20' } } return s.join('') }; 补充第二种方法 可以不要数组 谢谢@想见青山 var replaceSpace = function(s) { return s.split(' ').join("%20"); };