请实现一个函数,把字符数组中的每个空格替换为”%20”。例如输入”we are happy.”则输出”we%20are%20happy.”
原来的一个空格被替换为‘%’‘2’‘0’我们不能想当然的直接赋值字符,而必须将空格后面的所有字符都后移两个位置否则会覆盖原来的字符。
时间复杂度为O(n^2)的解法,不足以拿到Offer
在我们平常看到数组这玩意儿时我们总是从前往后遍历,同样在解答这题时也会从前往后一个个遍历,如果遇到空格就将空格后面的字符都后移2位,直至遇到结尾。拿题目中的例子来说由于遇到两个空格”happy.”这一部分被反复的向后移动了两次,这太多余了。
以下是这种解法的流程:
这种解法的代码我就不贴出来害人了,提及只是提醒大家!!!
时间复杂度为O(n)的解法,搞定Offer
从前往后遍历会导致部分字符重复的移动,那么如果我们从后向前遍历呢?
以下是从后向前的解法流程:
从后向前遍历中没有出现重复移动两次的现象,并且happy.在第一次移动中就移到了最终位置,这是因为字符数组中有两个空格,那么这个字符数组长度会增加4,我们能知道最终的结尾部分在哪里。从而直接将happy.移动到最终目的位置。
以下贴出这种解法的代码:
//从后往前扫描
public class ReplaceSpace {
public static void main(String[] args) {
String str = "we are happy.";
char[] chs = new char[20];
for(int i=0;i<str.length();i++){
chs[i] = str.charAt(i);
}
printf(replace(chs));
}
public static int strlen(char[] chs){
if(chs==null){
return -1;
}
int i=0,count=0;
while(chs[i]!='\0'){
i++;
count++;
}
return count;
}
public static void printf(char[] chs){
if(chs==null){
return;
}
int i=0;
while(chs[i]!='\0'){
System.out.print(chs[i]);
i++;
}
}
public static char[] replace(char[] chs){
if(chs==null){
return null;
}
char ch;
int i=0;
int j=i;
int count=0;//记录空格数
//首先遍历一遍记录下空格数目
while(chs[i]!='\0'){
if(chs[i]==' '){
count++;
}
i++;
}
i--;
//一个空格要后移2位,count个空格要后移2*count位
j = i + 2*count;
while(i>=0){
chs[j] = chs[i];
if(chs[i]==' '){
chs[j]='0';
chs[--j]='2';
chs[--j]='%';
}
i--;
j--;
}
return chs;
}
//使用char[]更麻烦一点,为了让C语言的看官看懂,使用StringBuffer更简短
public static String replaceSpace(StringBuffer str) {
int countSpace = 0;//countSpace为计算空格数
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' ')
countSpace++;
}
int indexold = str.length()-1; //indexold为为替换前的str下标
int newlength = str.length() + countSpace*2;//计算空格转换成%20之后的str长度
int indexnew = newlength-1;//indexold为为把空格替换为%20后的str下标
str.setLength(newlength);//使str的长度扩大到转换成%20之后的长度,防止下标越界
for(;indexold>=0 && indexold<newlength;--indexold){
if(str.charAt(indexold) == ' '){
str.setCharAt(indexnew--, '0');
str.setCharAt(indexnew--, '2');
str.setCharAt(indexnew--, '%');
}else{
str.setCharAt(indexnew--, str.charAt(indexold));
}
}
return str.toString();
}
}
测试结果: