本文參考自《劍指offer》一書,代碼采用Java語言。
題目
輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3, 32, 321},則打印出這3個數字能排成的最小數字321323。
思路
不好的方法:求出所有全排列(類似字符串的排列 ),將數字拼起來,最后求出所有的最小值。這效率太低,且沒有考慮到大數問題。
好的方法:觀察規律,自行定義一種排序規則。
對於數字m和n,可以拼接成mn和nm,如果mn<nm,我們定義m小於n。反之則相反。利用這個排序規則,從小排到大即可實現題目要求。
拼接m和n時,要考慮到大數問題,因此將m和n拼接起來的數字轉換成字符串處理。因為mn和nm的字符串位數相同,因此它們的大小只需要按照字符串大小的比較規則就可以了。
具體實現:將數字存入ArrayList中,通過利用Collections.sort(List<T> list, Comparator<? super T> c)方法進行排序。Comparator中重寫compar()方法來規定比較規則。
測試算例
1.功能測試(1個數字;多個數字;數字數位有重復)
2.特殊測試(null)
Java代碼
//題目:輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼
//接出的所有數字中最小的一個。例如輸入數組{3, 32, 321},則打印出這3個數
//字能排成的最小數字321323。
public class SortArrayForMinNumber {
public String PrintMinNumber(int [] numbers) {
if(numbers==null || numbers.length<=0)
return "";
ArrayList<String> list = new ArrayList<String>();
for(int number:numbers)
list.add(String.valueOf(number));
Collections.sort(list,new Comparator<String>(){
@Override
public int compare(String s1,String 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();
}
}
收獲
1.記住Collections.(List<T> list, Comparator<? super T> c)在重寫compare()方法的使用。
2.小心大數問題,用字符串解決大數問題。
3.遇到類似排序問題,想想自定排序規則是否更加方便。
