輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。
最先想到比較每一位的大小,由於最近看了基數排序,那就來一把變形的基數排序吧,代碼量有點大
public String PrintMinNumber(int[] numbers) {
if(numbers.length == 0) return "";
//將創建桶
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < 9; i++) {
map.put(i, new ArrayList<Integer>());
}
//獲得最大位數
int maxNum = getMaxNum(numbers);
int n = 1;
//循環到最高位
for (int i = 0; i < maxNum; i++) {
//將數組中的數如桶
for (int j = 0; j < numbers.length; j++) {
//獲取當前位上數字
int num;
if(numbers[j] < n) num = getHighNum(numbers[j]);
else num = numbers[j] / n % 10;
//加入到對應的桶中
map.get(num).add(numbers[j]);
}
//將桶中的數倒回數組
int index = 0;
for (List<Integer> nums : map.values()) {
while (nums.size() > 0) {
numbers[index++] = nums.get(0);
nums.remove(0);
}
}
n*=10;
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < numbers.length; i++) {
stringBuilder.append(numbers[i]);
}
return stringBuilder.toString();
}
public int getHighNum(int num) {
while (num >= 10) {
num = num / 10;
}
return num;
}
public int getMaxNum(int[] arr){
int max = getMax(arr);
int count = 0;
int n = 10;
while (max != 0) {
max = max / n;
count++;
}
return count;
}
public int getMax(int[] arr){
int max = Integer.MIN_VALUE;
for(int num : arr){
if(num > max) max = num;
}
return max;
}
覺得自己很牛逼了,看一下討論,發現傻逼了,直接巧妙的改變sort的排序規則就可以了,思路上能簡單很多 自己實現了一遍
public String PrintMinNumber2(int[] numbers) {
List<Integer> list = new ArrayList<>();
for (int num : numbers) {
list.add(num);
}
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return (Integer.parseInt(new String(o1+""+o2)) - Integer.parseInt(new String(o2 + "" +o1)));
}
});
StringBuilder stringBuilder = new StringBuilder();
for (int num : list) {
stringBuilder.append(num);
}
return stringBuilder.toString();
}
算上思考時間,有相差十倍之餘,唯一可以安慰的就是這種方法運行速度比我的慢了2毫秒…自我安慰