劍指Offer對答如流系列 - 把數組排成最小的數

面試題45:把數組排成最小的數

一、題目描述

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

二、問題分析

之前我們做過字符全排列的習題 劍指Offer對答如流系列 - 字符串的排列,但是將算法思想應用到這一題的話,效果不好,求出所有的組合,再計算出組合的最小值,這效率該多低啊。

我們還要進一步探究,看看有沒有不錯的規律,供我們使用。

因爲數字拼接後的長度一樣,拼接後的結果大亦或是小 首先取決於最高位的數字,然後再低位。

既然這樣,我們定義一下數學模型:
對於數字m和n,可以拼接成mn和nm,如果mn<nm,我們定義m小於n。反之則相反。利用這個排序規則,從小排到大即可實現題目要求。

在求解的時候:拼接m和n,要考慮到大數問題,因此將m和n拼接起來的數字轉換成字符串處理。
使用 String.compareTo 方法:
compareTo() 的返回值是int, 它是先比較對應字符的大小(ASCII碼順序)
1、如果字符串相等返回值0
2、如果第一個字符和參數的第一個字符不等,結束比較,返回他們之間的差值(ascii碼值)(負值前字符串的值小於後字符串,正值前字符串大於後字符串)
3、如果第一個字符和參數的第一個字符相等,則以第二個字符和參數的第二個字符做比較,以此類推,直至比較的字符或被比較的字符有一方全比較完,這時就比較字符的長度.

三、問題解決

 public String PrintMinNumber(int [] numbers) {
        if(numbers==null || numbers.length<=0) {
            return "";
        }
        ArrayList<String> list = new ArrayList<>();
        for(int number:numbers) {
            list.add(String.valueOf(number));
        }
        list.sort((s1, s2) -> {
            String a = s1 + s2;
            String b = s2 + s1;
            return a.compareTo(b);
        });
        StringBuilder sb= new StringBuilder();
        for(String str:list)
            sb.append(str);
        return sb.toString();
    }
發佈了194 篇原創文章 · 獲贊 3472 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章