题目描述:
请实现一个函数,将一个字符串中的空格替换成”%20”。例如,当字符串为We Are Happy,则经过替换之后的字符串为We%20Are%20Happy。
直接使用StringBuffer的例程:牛客AC
public class Solution {
public String replaceSpace(StringBuffer str) {
StringBuffer strNew = new StringBuffer();
String strIni = str.toString();
for(int i = 0; i < str.length(); i++) {
char c = strIni.charAt(i);
if(c ==' ') {
strNew.append("%20");
} else {
strNew.append(c);
}
}
return strNew.toString();
}
}
推荐解法:牛客AC
从尾部循环替换的思想(在冒泡排序算法之中也是从尾部往前进行比较然后交换的),于是形成如下的思路:首先统计出该字符串中所有的空格数量,并重新计算新串所需的char数组的长度,把旧串转化成的char数组拷贝到一个临时数组中,并同时创建一个新的char数组,该新数组的长度是计算之后的长度。从该新数组的尾部开始循环,依次往前比较,只要遇到了空格就替换为%20。如果没有遇到空格就直接复制过来就行。
public String replaceBlank(String str) {
if(str == null || str.length() <= 0)
return " ";
// 统计空格数目
int blankCount = 0;
char[] charArr = str.toCharArray();
for(char c : charArr) {
if(c == ' ')
blankCount++;
}
int iniLength = str.length();
int newLength = iniLength + blankCount * 2;
char[] resArr = new char[newLength];
// 复制一份数组
for(int i = 0; i < iniLength; i++) {
resArr[i] = charArr[i];
}
int iniIndex = iniLength - 1;
int newIndex = newLength - 1;
// 替换空格
while(iniIndex >= 0 && iniIndex != newIndex) {
System.out.println(iniIndex + " " + newIndex);
if(charArr[iniIndex] == ' ') {
resArr[newIndex--] = '0';
resArr[newIndex--] = '2';
resArr[newIndex--] = '%';
} else {
resArr[newIndex--] = charArr[iniIndex];
}
iniIndex--;
}
String resStr = new String(resArr); // 有char数组生成String
return resStr;
}
由于只有一层循环,加上统计空格的时间开销和复制数组的时间开销,就是两个循环的时间开销,其他的操作都是 O(1) 的时间复杂度。所以该算法综合起来的时间复杂度是 O(n) 。
相关题目:
有两个排序数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2。请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字都是排序的。
总结:
合并两个数组(包括字符串)时,如果从前往后赋值每个数字(或者字符串),需要重复移动数字或字符多次。可以考虑从后往前进行处理,减少移动次数,提高效率。
参考
1. 何海涛,剑指offer名企面试官精讲典型编程题(纪念版),电子工业出版社