劍指Offer_32_把數組排成最小的數

題目描述

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

解題思路

  1. 解法1
    使用全排列方式,將所有的可能排列出來,每次得到一個排列,記錄其中的最小的一個值。

  2. 解法2
    第一種解法需要求解所有的排列,時間複雜度高。我們可以使用一種排序算法,實現對數據排序。排序規則是,當兩個數拼接在一起, 如 mn < nm,那麼 m 就小於 n。

實現

  1. 解法1
public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if (numbers == null || numbers.length <= 0) return "";

        return recursion(numbers, 0, "");
    }

    private String recursion(int[] numbers, int i, String s) {

        if (i == numbers.length) return s;

        String min = null;

        for (int j = i; j < numbers.length; j++){
            swap(numbers, i, j);

            String now = recursion(numbers, i + 1, s+numbers[i]);

            min = min == null ? now : (min.compareTo(now) < 0 ? min : now);

            swap(numbers, i, j);
        }
        return min;
    }

    private void swap(int[] numbers, int i, int j) {
        int tmp = numbers[i];
        numbers[i] = numbers[j];
        numbers[j] = tmp;
    }
}
  1. 解法2
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if (numbers == null || numbers.length <= 0) return "";
        sort(numbers, 0, numbers.length-1,new Comparator<Integer>(){

            @Override
            public int compare(Integer o1, Integer o2) {
                StringBuilder sb1 = new StringBuilder();
                sb1.append(o1).append(o2);
                StringBuilder sb2 = new StringBuilder();
                sb2.append(o2).append(o1);
                String s1 = sb1.toString();
                String s2 = sb2.toString();
                return s1.compareTo(s2);
            }
        });
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < numbers.length; i++){
            sb.append(numbers[i]);
        }
        return sb.toString();
    }

    private void sort(int[] numbers, int start, int end, Comparator<Integer> comparator) {
        int p = partion(numbers, start, end, comparator);
        if (start < p){
            sort(numbers, start, p-1, comparator);
        }
        if (end > p && p != -1){
            sort(numbers, p+1,end,comparator);
        }
    }

    private int partion(int[] numbers, int start, int end, Comparator<Integer> comparator) {

        if (start > end) return -1;

        int tmp = numbers[start];

        while (start < end){
            while (start < end && comparator.compare(numbers[end],tmp) >= 0) end--;

            if (start < end)
                numbers[start++] = numbers[end];

            while (start < end && comparator.compare(numbers[start],tmp) < 0) start++;

            if (start < end)
                numbers[end--] = numbers[start];
        }

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