把數組排列成最小的數

題目描述
輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。

思路一:
排列出數組所有可能的組合,找出其中最小的數。難點在於求所有可能的組合,求解過程和求一串字符的字典序類似。如下所示:
這裏寫圖片描述
(圖片來源於網絡)
僞代碼如下:

mothed(int[] arr, int start, int end)
tmp = min(arr, tmp);
for each i in [start, end]
    swap(i, start);
    mothed(start+1, end);
    swap(i, start);

真實代碼如下:

public class Main {

    static String min = null;

    public static void main(String args[]) {
        int[] arr = {3, 32, 321};
        StringBuffer first = new StringBuffer();
        for(int t : arr)
            first.append(t);
        min = first.toString();
        findMin(arr,0, arr.length - 1);
        System.out.println(min);
    }

    public static void findMin(int[] arr, int start, int end) {
        if (start <= end) {
            StringBuffer sb = new StringBuffer();
            for (int k : arr)
                sb.append(k);
            if(min.compareTo(sb.toString()) > 0)
                min = sb.toString();
            for (int i = start; i <= end; i++) {
                swap(arr, start, i);
                findMin(arr, start + 1, end);
                swap(arr, start, i);
            }
        }
    }

    public static void swap(int[] arr, int index1, int index2) {
        int t = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = t;
    }
}

算法特性:
空間複雜度較高,時間複雜度也高;
輸出:

321323

思路二:
從題目中可以發現: 以32 和 3 的組合爲例,要是排列後數最小,必須32 在 3 之前,同理 321 必須在 32 之前。那麼定義一種比較規則:
對於整數 x 和 y,xy表示x和y按順序拼接後的整數
if xy > yx , then x > y;
if xy < yx , then x < y;
else x = y;
於是思路就明瞭了,先利用Arrays.sort()按定義的比較規則對輸入數組進行排序,再將數組按次序拼接,得到的值即爲最小數。

public class Main {

    public static void main(String args[]) {
        Integer[] arr = {3, 32, 321};
        Arrays.sort(arr, new Compare());
        StringBuffer sb = new StringBuffer();
        for (int i : arr)
            sb.append(i);
        System.out.println(sb);
    }
}

class Compare implements Comparator<Integer> {

    @Override
    public int compare(Integer i1, Integer i2) {
        return (String.valueOf(i1) + String.valueOf(i2)).compareTo(String.valueOf(i2) + String.valueOf(i1));
    }
}

輸出:

321323

算法特性:時間複雜度相對較低O(nlogn),但是空間複雜度較高O(nlogn).
String.valueOf(i1) + String.valueOf(i2)先根據i1和i2生成兩個String對象,拼接在一起生成第三個String對象。每比較一次,均要生成多個String對象,因此空間複雜度爲O(nlogn).

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