题目
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
解题思路
- 第一反应是
replace
对不对?API大家都会用,但是replace的底层是遍历查找,然后添加,由于要替换的字符数大于原字符数,因此会导致后面的字符进行复制移动,因此除了最后一个是空格的情况下,有几个空格就要遍历几次,就要复制几次字符数组,空间和时间复杂度都很高 - 第二种思路自然就是再建一个
StringBuffer
,然后比较字符进行复制,这种做法的时间复杂度和空间复杂度都是n - 第三种思路是不新建一个
StringBuffer
,而是用原来那个,先遍历一遍统计出总的空格数量,然后算出总长度并将源StringBuffer
的长度修改为改长度,同时为了防止覆盖,采用从后向前替换的方式,采用双指针移动字符位置。由于提前计算好的总长度,因此在倒历时达到头部的空格两个指针才会碰到一起,否则旧指针数据不会受到影响
解题代码
public static String replaceSpace(StringBuffer str) {
if (str == null) return null;
int blankNum = 0;
for (int i=0;i<str.length();i++){
if (str.charAt(i) == ' '){
blankNum++;
}
}
// 旧长度
int oldLength = str.length();
// 指向旧字符串的指针
int oldIndex = oldLength-1;
// 新的总长度
int totalLength = str.length()+blankNum*2;
// 新buffer的倒历指针
int index = totalLength-1;
str.setLength(totalLength);
while (oldIndex>=0){
char c = str.charAt(oldIndex);
if (c == ' '){
str.setCharAt(index--,'0');
str.setCharAt(index--,'2');
str.setCharAt(index--,'%');
}else {
str.setCharAt(index--,c);
}
oldIndex--;
}
return str.toString();
}