劍指offer-chapter2-面試題4-替換空格(java)

題目: 替換空格

請實現一個函數,吧字符串中的每個空格替換成 “%20”。例如輸入 “We are happy.” , 這輸出“We%20arehappy.”。(不使用replace&insert方法和必須在原串中改變)

解題思路:

解法1:

思路: 複雜度O(n²),遍歷所有字符並添加後移動後面的字符串(不推薦)。
如字符串“We are happy.”:

初始化:

W e a r e h a p p y .

第一次移動(陰影代表需要移動的字符):

W e % 2 0 a r e h a p p y .

第二次移動(深色配筋說明需要移動兩次):

W e % 2 0 a r e % 2 0 h a p p y .

由此思路可知時間複雜度O(n²),可寫出代碼:

//    複雜度O(n²),遍歷所有字符並在添加後空格後面的字符串向後移動(不推薦)
    public static StringBuilder replace1(StringBuilder target) {
        if (target == null) {
            return null;
        }
        for (int i = 0; i < target.length(); i++) {
            if (target.charAt(i) == ' ') {
                StringBuilder template = new StringBuilder(target);
                //改變原來String的長度,增加2
                target.setLength(target.length() + 2);
                target.setCharAt(i, '%');
                target.setCharAt(i + 1, '2');
                target.setCharAt(i + 2, '0');
                for (int j = i + 3; j < target.length(); j++) {
                    target.setCharAt(j, template.charAt(j - 2));
                }
                i += 2;
            }
        }
        return target;
    }

解法2:

思路:既然我們需要替換空格,那我們可不可以先對空格進行計數,然後拓展數組大小,再從後向前進行賦值呢?

W e a r e h a p p y .

由字符串可知空格有2個,故需拓展4個大小,p1,p2分別爲原來和拓展後的最後一個字符的位置:

W e a r e h a p p y .
p1 p2

將p1的下標的值賦給p2:

W e a r e h a p p h a p p y .
p1 p2

若是空格則賦 %20三個字符:

W e a r e h % 2 0 h a p p y .
p1 p2

則到終點爲:

W e % 2 0 a r e % 2 0 h a p p y .
p1. p2

故可寫出代碼:

    //    複雜度O(n),先記錄空格個數在進行替換移動。
    public static StringBuilder replace2(StringBuilder target) {
        if (target == null) {
            return null;
        }
//        記錄空格個數
        int spaceNum = 0;
        for (int i = 0; i < target.length(); i++) {
            if (target.charAt(i) == ' ') {
                spaceNum++;
            }
        }
//        以前下標
        int oldIndex = target.length() - 1;
//        新的長度
        int newLength = target.length() + spaceNum * 2;
//        新下標
        int newIndex = newLength - 1;
        target.setLength(newLength);
//        這裏注意:
//          1.循環是從後往前,這樣可以避免重複移動
//          2.判斷條件:oldIndex < newIndex && newIndex >= 0 則無需全部遍歷,若oldIndex<newIndex則代表所有空格已經被替換
        for (; oldIndex < newIndex && newIndex >= 0; oldIndex--) {
            if (target.charAt(oldIndex) == ' ') {
//                這裏由於是從後向前循環,所以插入字符也應該倒插
                target.setCharAt(newIndex--, '0');
                target.setCharAt(newIndex--, '2');
                target.setCharAt(newIndex--, '%');
            } else {
                target.setCharAt(newIndex--, target.charAt(oldIndex));
            }
        }

        return target;
    }

完整代碼如下:

package problem4;

/**
 * 題目: 替換空格
 * 請實現一個函數,吧字符串中的每個空格替換成 “%20”。例如輸入 “We are happy.” , 這輸出“We%20arehappy.”。(不使用replace&insert方法和必須在原串中改變)
 * Created by fengyuwusong on 2018/1/16 14:57.
 */
public class ReplaceSpance {
    //    複雜度O(n²),遍歷所有字符並添加後移動(不推薦)
    public static StringBuilder replace1(StringBuilder target) {
        if (target == null) {
            return null;
        }
        for (int i = 0; i < target.length(); i++) {
            if (target.charAt(i) == ' ') {
                StringBuilder template = new StringBuilder(target);
                //改變原來String的長度,增加2
                target.setLength(target.length() + 2);
                target.setCharAt(i, '%');
                target.setCharAt(i + 1, '2');
                target.setCharAt(i + 2, '0');
                for (int j = i + 3; j < target.length(); j++) {
                    target.setCharAt(j, template.charAt(j - 2));
                }
                i += 2;
            }
        }
        return target;
    }

    //    複雜度O(n),先記錄空格個數在進行替換移動。
    public static StringBuilder replace2(StringBuilder target) {
        if (target == null) {
            return null;
        }
//        記錄空格個數
        int spaceNum = 0;
        for (int i = 0; i < target.length(); i++) {
            if (target.charAt(i) == ' ') {
                spaceNum++;
            }
        }
//        以前下標
        int oldIndex = target.length() - 1;
//        新的長度
        int newLength = target.length() + spaceNum * 2;
//        新下標
        int newIndex = newLength - 1;
        target.setLength(newLength);
//        這裏注意:
//          1.循環是從後往前,這樣可以避免重複移動
//          2.判斷條件:oldIndex < newIndex && newIndex >= 0 則無需全部遍歷,若oldIndex<newIndex則代表所有空格已經被替換
        for (; oldIndex < newIndex && newIndex >= 0; oldIndex--) {
            if (target.charAt(oldIndex) == ' ') {
//                這裏由於是從後向前循環,所以插入字符也應該倒插
                target.setCharAt(newIndex--, '0');
                target.setCharAt(newIndex--, '2');
                target.setCharAt(newIndex--, '%');
            } else {
                target.setCharAt(newIndex--, target.charAt(oldIndex));
            }
        }

        return target;
    }


    public static void main(String[] args) {
//        編寫測試用例
//        第一個方法
//        開頭空
        System.out.println(replace1(new StringBuilder(" 2354")));
//        結尾空
        System.out.println(replace1(new StringBuilder("2345 ")));
//        中間空
        System.out.println(replace1(new StringBuilder("23 56")));
//        全部情況一起
        System.out.println(replace1(new StringBuilder(" 2 34 ")));
//        空
        System.out.println(replace1(null));
        System.out.println(replace1(new StringBuilder("")));
//        單獨空格
        System.out.println(replace1(new StringBuilder(" ")));
//        連續空格
        System.out.println(replace1(new StringBuilder("   ")));
        System.out.println("----------------------");
//        第二個
//        開頭空
        System.out.println(replace2(new StringBuilder(" 2354")));
//        結尾空
        System.out.println(replace2(new StringBuilder("2345 ")));
//        中間空
        System.out.println(replace2(new StringBuilder("23 56")));
//        全部情況一起
        System.out.println(replace2(new StringBuilder(" 2 34 ")));
//        空
        System.out.println(replace2(null));
        System.out.println(replace2(new StringBuilder("")));
//        單獨空格
        System.out.println(replace2(new StringBuilder(" ")));
//        連續空格
        System.out.println(replace2(new StringBuilder("   ")));
    }

}

相關問題:

有兩個排序的數組A1和A2,內存在A1的末尾有足夠的空餘空間容納A2。
請事先一個函數,把A2中的所有數字插入到A1中並且所有的數字是排序的。

解題思路:

解題思路:從尾到頭比較A1和A2中的數字,並把較大的數字複製到A1的合適位置。
代碼:

package problem4;

/**
 * 相關問題:
 * 有兩個排序的數組A1和A2,內存在A1的末尾有足夠的空餘空間容納A2。
 * 請事先一個函數,把A2中的所有數字插入到A1中並且所有的數字是排序的。
 * Created by fengyuwusong on 2018/1/16 23:00.
 */
public class Relative {
    //解題思路:從尾到頭比較A1和A2中的數字,並把較大的數字複製到A1的合適位置。
    public static int[] merge(int[] a1, int[] a2, int a1Length, int a2Length) {
//        a1的下標
        int a1Index = a1Length - 1;
//        a1的下標
        int a2Index = a2Length - 1;
//        合併後總下標
        int mergeIndex = a1Length + a2Length - 1;
//        判斷長度是否足夠
        if (a1.length < mergeIndex + 1) {
            System.out.println("a1長度不夠");
            return null;
        }
//        進行從後向前循環比較並替換   優勢:不用移動前面的數字
        while (a1Index >= 0 && a2Index >= 0) {
            if (a1[a1Index] >= a2[a2Index]) {
                a1[mergeIndex] = a1[a1Index];
                a1Index--;
                mergeIndex--;
            } else {
                a1[mergeIndex] = a2[a2Index];
                a2Index--;
                mergeIndex--;
            }
        }

//        考慮情況a2比a1長度長,此時a1已經沒有數字,則將a2剩餘數字放在數組前面
//        無需考慮a1情況,因爲a2本身已經在數組a1中
        while (a2Index >= 0) {
            a1[mergeIndex] = a2[a2Index];
            a2Index--;
            mergeIndex--;
        }
        return a1;
    }

    public static void show(int[] a1) {
        if (a1 == null) {
            return;
        }
        for (int i = 0; i < a1.length; i++) {
            System.out.print(a1[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] a1 = {1, 3, 6, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        int[] a2 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
//        a2比a1長
        a1 = merge(a1, a2, 5, 9);
        show(a1);
//        a2比a1短
        int[] a3 = {0, 1, 3, 6, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        int[] a4 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        a1 = merge(a3, a4, 6, 3);
        show(a1);
//        a1長度不夠
        int[] a5 = {1, 3, 6, 9, 10};
        int[] a6 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        a1 = merge(a5, a6, 5, 3);
        show(a1);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章