背景知识:在网络编程哪个,如果URL参数中含有特殊字符,则可能导致服务器端无法获得正确的参数值。因此需要转换字符,而规则是在'%'后面加上ASCII码的两位十六进制表示,因此空格的替换就是%20


思路1:

显然一个空格字符变成了'%''2''0'三个字符,因此原来的字符串会变长。因此这里有思路0:从头到尾扫描,碰见空格就替换,然后对后面的字符都后移,这样的时间复杂度是O(n^2),所以思路1对0进行改进。
那就是先遍历一次字符串,这样就能统计出空格数,而替换时,从字符串后面移动,这样所有非空格字符串都只移动了一次。这样复杂度就变成了O(n)
那么先考虑将原字符串的长度改变,然后移动。当从后面往前面添加,需要两个变量(指针),一个记录新长度的原字符串更新处的索引,一个记录原长度字符串即将更新的字符串。

//java的StringBuffer是长度可变的
public class Solution {
    public String replaceSpace(StringBuffer str) {
        int count = 0;
        for(int i = 0; i < str.length(); i++){
            if(str.charAt(i) == ' '){
                count++;
            }
        }
        int oldLength = str.length();
        int oldIndex = oldLength - 1;
        int newLength = oldLength + count * 2;
        str.setLength(newLength);
        int newIndex = newLength - 1;
        for(; oldIndex >= 0 && oldLength < newLength; oldIndex--){
            if(str.charAt(oldIndex) == ' '){
                str.setCharAt(newIndex--, '0');
                str.setCharAt(newIndex--, '2');
                str.setCharAt(newIndex--, '%');
            }else{
                str.setCharAt(newIndex--, str.charAt(oldIndex));
            }
        }
        return str.toString();
    }
}

思路2:

开辟一个新的字符串做替换。思想和思路1大部分相同,统计空格次数,然后也是从后一个个添加。
而思路1的指向新长度的原字符串的指针,变成指向了新字符串的指针。

public class Solution {
    public String replaceSpace(StringBuffer str) {
        if (str == null) {
            return null;
        }
        int count = 0;
        int length = str.length();
        for (int i = 0; i < length; i++) {
            if (str.charAt(i) == ' ') {
                count++;
            }
        }
        int newLength = length + 2 * count;//替换后的字符串长度
        char[] newChars = new char[newLength];//新的字符数组
        int index = newLength - 1;
        for(int i=length-1;i>=0;i--) {
            if (str.charAt(i) == ' ') {
                newChars[index--] = '0';
                newChars[index--] = '2';
                newChars[index--] = '%';
            } else {
                newChars[index--] = str.charAt(i); 
            }
        }
        return new String(newChars);
      //return String.valueOf(newChars);
    }
}

思路3:java自己的方法

需要对java的API有一定的了解,就可以写出不同的方式。利用replace或者append又或者其他方式。本题的本意是要掌握之前的算法思想!!

public class Solution {
    public String replaceSpace(StringBuffer str) {    
        return str.toString().replace(" ","%20");
      //return str.toString().replaceAll("\\s","%20");正则表达式
    }
}

又或者可以写成

public class Solution {
    public String replaceSpace(StringBuffer str) {
        String s = str.toString();
        if(str==null)
            return s;
         char [] ch = s.toCharArray();
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < ch.length; i++)
            {
            if(ch[i]==' ')
                {
                 sb.append("%20");
            }
           else
               sb.append(ch[i]);
        }
        return sb.toString();
    }
}