題目描述
- 輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字為321323。
解題思路
- 將數組數字重排為最小的數字連接形式,那么直接遍歷數組就可以得到我們想要的結果
- 那么問題來了怎么重組這個排序呢,按照一般的數字排序,就是兩個數比較大小然后交換位置,那么這個組合成字符串的我們可以采用兩個數字a和b組合成字符串ab和字符串ba比較這兩個字符串的大小來確定他們的位置,如果說ab結果比較小,那就代表不需要交換,如果ba小那就代表需要將數字b挪到a之前進行一次交換
- 確定了比較方法現在需要確定排序方法,排序有N種方法,歸并/堆排/快排/選擇/插入/希爾/冒泡等一堆方法,當然快的也就是快排了,時間復雜度O(nlogn)那就這個了
- 方法和數字的數組快排完全一樣,只是將交換的判斷條件更改為2中所述的內容即可
- 最后遍歷數組重組為字符串
Java源代碼
import java.util.ArrayList;
public class Solution {
public String PrintMinNumber(int [] numbers) {
sort(numbers, 0, numbers.length-1);
String result = "";
for (int i=0; i<numbers.length; i++) result += String.valueOf(numbers[i]);
return result;
}
private static void sort(int[] nums, int lo, int hi) {
if (hi<=lo) return;
int j = partion(nums, lo, hi);
sort(nums, lo, j-1);
sort(nums, j+1, hi);
}
private static int partion(int[] nums, int low, int high) {
int key = nums[low];
while (low<high) {
while (low<high && compare(key, nums[high])) high--;
if (low<high) nums[low] = nums[high];
while (low<high && compare(nums[low], key)) low++;
if (low<high) nums[high] = nums[low];
}
nums[low] = key;
return low;
}
private static boolean compare(int a, int b) {
String ab = String.valueOf(a) + String.valueOf(b);
String ba = String.valueOf(b) + String.valueOf(a);
return ab.compareTo(ba)<=0;
}
}