【劍指offer第二版Java】面試題5:替換空格

題目:請實現一個函數,把字符串中的每個空格替換成 “%20”。 例如輸入 “We are happy.”,則輸出”We%20are%20happy.”。


注意:

  1. 空格會被替換成"%20"
  2. String、SringBuffer和StringBuilder區別

解決方案:

(面試時視面試官要求而定,需要詢問清楚下面兩種不同情況)

  1. 如果在原來的字符串上進行替換,就有可能覆蓋修改在該字符串後面的內存
  2. 如果時創建新的字符串並在新的字符串上進行替換,那麼我們可以自己分配足夠多的內存

兩種不同的替換操作解法(採用的時創建新的字符串並在新的字符串上進行替換):

1、時間複雜度爲O(n2)的解法,不足以拿到offer

最直觀的做法就是從頭到尾掃描字符串,每次碰到空格字符的時候就進行替換。由於是把1個字符替換成3個字符,因此必須把空格後面的所有字符都要後移2個字節,否則就會有兩個字符被覆蓋了。

假設字符串的長度是n,對每個空格字符,需要移動後面O(n)個字符,因此對於含有O(n)個空格字符的字符串而言,總的時間效率是O(n2)。

代碼如下:

public class ReplaceSpace_05 {
    //方法一:時間複雜度爲O(n2),從前往後遍歷打印
    public static String replaceSpace1(String str) {
        if (str == null || str.length() <= 0) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == ' ') {
                sb.append('%');
                sb.append('2');
                sb.append('0');
            } else {
                sb.append(String.valueOf(str.charAt(i)));
            }
        }
        return new String(sb);
    }
    public static void main(String[] args) {
        String str1 = "We are happy.";
        System.out.println(replaceSpace1(str1));
    }
}

2、時間複雜度爲O(n)的解法

1、 首先遍歷一次字符串,統計出字符串中的空格總數,再計算出替換之後的字符串的總長度。每替換一個空格,長度增加2,因此替換以後字符串的長度等於原來的長度加上2乘以空格數目。

2、然後從字符串的後面開始複製和替換,首先準備兩個指針,P1和P2,P1指向原始字符串的末尾,而P2指向替換之後的字符串的末尾。

3、接下來向前移動指針P1,逐個把它指向的字符複製到P2指向的位置,直到碰到空格爲止。碰到空格後,把P1向前移動1格,在P2之前插入字符串”%20“,由於”%20“的長度爲3,同時也要把P2向前移動3格。後面每次遇到空格後都這樣做,直到P1和P2指向同一個位置,表明所有的空格已經替換完畢。

這種從後外向前的替換過程,所有的字符串只複製(移動)一次,因此這個算法的時間效率是O(n)。

代碼如下:
 

/**
 * ClassName : ReplaceSpace_05
 * package : PACKAGE_NAME
 *
 * @Descriptions : TODO
 * @Author : innerpeace
 * @Date : 2019/5/30 15:56
 * @Version V1.0.0
 * @Since 1.0
 */
public class ReplaceSpace_05 {

    //進階方法二:時間複雜度爲O(n),從後往前遍歷
    public static void replaceSpace2(String str){
        if(str == null || str.length() <= 0){
            System.out.println("您輸入的參數有問題!!!");
        }

        // 字符串的原始長度
        int oldLength= str.length();
        // 字符串替換後的長度
        int newLength = str.length() + getSpaceNumber(str) * 2;

        char[] newArr = new char[newLength];
        // 將str複製到新建的 newArr 數組中
        System.arraycopy(str.toCharArray(), 0, newArr, 0, str.toCharArray().length);
        int indexOfOriginP1 = oldLength - 1;
        int indexOfNewP2 = newLength - 1;
        System.out.println("未替換空格時的字符串:");
        printArray(str.toCharArray());

        while(indexOfOriginP1 >= 0 && indexOfOriginP1 != indexOfNewP2){
            if(newArr[indexOfOriginP1] == ' '){
                newArr[indexOfNewP2--] = '0';
                newArr[indexOfNewP2--] = '2';
                newArr[indexOfNewP2--] = '%';
            }else{
                newArr[indexOfNewP2--] = newArr[indexOfOriginP1];
            }
            indexOfOriginP1--;
        }

        System.out.println("替換後的字符串爲:");
        printArray(newArr);
    }

    // 獲取空格數
    private static int getSpaceNumber(String str) {
        int count = 0;   // 空格數
        for (int i = 0; i < str.length(); i++) {
            // 獲取str中下標爲i的元素,判斷它是否爲空格
            String gsn = String.valueOf(str.charAt(i));
            if(gsn.equals(' ')){
                count++;
            }
        }
        return count;
    }

    // 打印char[]數組
    public static void printArray(char[] arr){
        for(char i : arr){
            System.out.print(i);
        }
        System.out.println();
    }

    //測試
    public static void main(String[] args) {
        String str1 = "We are happy.";
        replaceSpace2(str1);
    }
}

測試結果:第一行爲方法一結果;第二行之後爲方法二結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章