剑指 Offer 45. 把数组排成最小的数

62 阅读1分钟

题目:
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
算法:
试试mergeSort。sort算法得变种,主要是less函数得变化

func minNumber(nums []int) string {
    mergeSort(nums, 0, len(nums) - 1)
    ans := ""
    // fmt.Println(nums)
    for i := range nums {
        ans = fmt.Sprintf("%s%d",ans,nums[i])
    }
    return ans
}

func mergeSort(nums []int, left, right int) {
    if left == right {
        return
    }
    mid := (left + right) / 2
    mergeSort(nums, left, mid)
    mergeSort(nums, mid + 1, right)
    tmp := make([]int, 0)
    leftStart, rightStart := left, mid + 1
    for leftStart <= mid && rightStart <= right {
        if less(nums[leftStart], nums[rightStart]) {
            tmp = append(tmp, nums[leftStart])
            leftStart ++
        } else {
            tmp = append(tmp, nums[rightStart])
            rightStart ++
        }
    }
    for leftStart <= mid {
            tmp = append(tmp, nums[leftStart])
            leftStart ++
    }
    for rightStart <= right {
            tmp = append(tmp, nums[rightStart])
            rightStart ++
    }
    for i := 0; i < len(tmp); i ++ {
        nums[left + i] = tmp[i]
    }
}

func less(a, b int) bool {
    // 注意这个边界条件,有0得情况下不能走下面的逻辑。
    // 因为[0,1]排序会得到0111,而不是0110
    if a == 0 || b == 0 {
        return a < b
    }
    aWeight, bWeight := 1, 1
    copyA, copyB := a, b
    for copyA > 0 {
        aWeight = aWeight * 10
        copyA = copyA / 10
    }
    for copyB > 0 {
        bWeight = bWeight * 10
        copyB = copyB / 10
    }
    // fmt.Println(a, aWeight, b, bWeight)
    return (a * bWeight + b) < (b * aWeight + a)
}