1、题目描述
【JZ02】请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
知识点:字符串。
难度:☆☆
2、解题思路
2.1 新建字符串
新建一个字符串 newStr,遍历输入字符串 oldStr 的每一个字符,遇到空格则 append 字符串 %20 ,否则直接 append 原字符串的字符。
2.2 扩展字符串
新建字符串的问题在于多创建了一个空间为 N 的字符串。
另外一个解决思路就是在原有的字符串上进行拓展。
拓展分为从前向后和从后向前,从前向后遍历的话,每遇到一个空格,都得把后面的字符往后挪,额外操作太多。
从后往前,先计算需要多少空间,然后从后往前移动,则每个字符只为移动一次,这样效率更高一点。
3、解题代码
3.1 新建字符串
package pers.klb.jzoffer.hard;
import java.util.*;
/**
* @program: JzOffer2021
* @description: 替换空格
* @author: Meumax
* @create: 2020-08-11 10:43
**/
public class ReplaceSpace {
public String replaceSpace(StringBuffer str) {
if (str == null || str.length() == 0) return str.toString();
StringBuilder newstr = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (' ' == str.charAt(i)) {
newstr.append('%');
newstr.append('2');
newstr.append('0');
} else {
newstr.append(str.charAt(i));
}
}
return newstr.toString();
}
}
时间复杂度:O(N),遍历一次原字符串。
空间复杂度:O(N),新建和原字符串一样大小的空间。
3.2 拓展字符串
package pers.klb.jzoffer.hard;
/**
* @program: JzOffer2021
* @description: 替换空格
* @author: Meumax
* @create: 2020-08-11 10:43
**/
public class ReplaceSpace {
public String replaceSpace(StringBuffer str) {
if (str.length() == 0) return str.toString(); //非空判断
int spaceCount = 0; // 空格的个数
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ' ') {
spaceCount++;
}
}
int oldIndex = str.length() - 1; // 原字符串最后一个字符的索引
int newLength = str.length() + spaceCount * 2; // 新的长度
str.setLength(newLength); // 拓展 str 的长度
int newIndex = newLength - 1; // 拓展后字符串最后一个字符的索引
// 从后向前遍历
while (oldIndex >= 0) {
if (str.charAt(oldIndex) == ' ') {
str.setCharAt(newIndex--, '0');
str.setCharAt(newIndex--, '2');
str.setCharAt(newIndex--, '%');
oldIndex--;
} else {
str.setCharAt(newIndex, str.charAt(oldIndex));
newIndex--;
oldIndex--;
}
}
return str.toString();
}
}
时间复杂度:O(2N),遍历了两次原数组。
空间复杂度:O(M),M为空格的个数。
4、解题心得
本题不能简单直接使用 replace 函数,因为该函数是替换字符,而本题是字符替换为字符串。
最简单的解决方法就是创建新的字符串,然后扫描赋值,遇到非空格直接赋值,遇到空格就输入替代的字符串;
稍微绕一点的思路就是对字符串进行拓展。
拓展字符串属于时间换空间,可以兼容取舍。