题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
public class Solution {
public String replaceSpace(StringBuffer str) {
}
}
思路
我们拿到题目的时候第一反应可能是声明一个新的字符串,直接遍历,然后添加到新字符串。
但是,当我们深入思考时会发现,开辟新的空间会增加空间复杂度,我们为什么不能在原有的长度足够的空间中进行替换呢。
方法一
直接遍历法
public static String replaceSpace(StringBuffer str) {
//声明一个StringBuffer对象,用作新字符串的存储
StringBuffer res = new StringBuffer(str.length());
//遍历字符串str,并加入到新的空间中
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ' '){
res.append("%20");
} else {
res.append(str.charAt(i));
}
}
return res.toString();
}
方法二
replaceAll方法
public static String replaceSpace(StringBuffer str) {
return str == null ? null : str.toString().replaceAll(" ", "%20");
}
方法三
在原有空间进行字符移动
我们的惯性思维是从前往后替换空格,但我们从前往后开始替换的话,比如遇到第一个空格,这个空格后的所有字符需要移动两位,而当我们遇到第二的空格时,又要移动第二个空格后的所有字符,造成了时间的浪费。
这时我们就考虑到了从后往前替换空格,我们可以先遍历一遍空格个数,根据空格个数我们可以得到扩展后的字符串长度
这样就可以从后往前依次替换了。
public static String replaceSpace(StringBuffer str) {
int count = 0; //空格数量
//求空格数量
//我们要根据空格数量求得字符串扩增后的长度
//扩增后长度=count*2+str.length()
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' '){
count++;
}
}
//原始字符串最大下标
int old_length = str.length()-1;
//设置新的字符串长度
str.setLength(count*2+str.length());
//新的字符串最大下标
int new_length = str.length()-1;
//从旧字符最后一位开始对新的字符串从后往前赋值
//每一次赋值都要使新字符的下标向前位移一位
for(int j=old_length;j>=0;j--){
if(str.charAt(j)!=' '){
str.setCharAt(new_length--, str.charAt(j));
}
else{
str.setCharAt(new_length--, '0');
str.setCharAt(new_length--, '2');
str.setCharAt(new_length--, '%');
}
}
//需要注意,返回值是Sting类型,而现在的str是StringBuffer类型
return str.toString();
}