剑指offer_45_把数组排成最小的数【javascript】

47 阅读1分钟

题目链接

leetcode.cn/problems/ba…

题目

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如,输入数组{3, 32, 321}, 则打印这3个数字能排成的最小数字321323。

提示:

  • 0 < nums.length <= 100
  • 输出结果可能非常大,所以你需要返回一个字符串而不是整数
  • 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

题解

JS API

var minNumber = function (nums) {
  nums = nums.sort((a, b) => {
    return Number(String(a) + b) - Number(String(b) + a)
  })
  // console.log(nums)
  return nums.join('')
};
// 更简洁
var minNumber = function (nums) {
  return nums.sort((a, b) => `${a}${b}` - `${b}${a}`).join("");
};

快速排序

复杂度分析:

  • 时间复杂度 O(Nlog⁡N) : N 为最终返回值的字符数量。
  • 空间复杂度 O(N): 字符串列表 strs 占用线性大小的额外空间。
/**
 * @param {number[]} nums
 * @return {string}
 */
var minNumber = function(nums) {

    return quicksort(nums).join('');
    
    function quicksort(nums) {
      
        if (nums.length < 2) return nums;
        
        let idx = Math.floor(nums.length / 2) //找个比较基准(partition)
        let p = nums.splice(idx, 1)   //从原数组切掉该基准, p是一个数组
        let L = [], R = []    //创建左右空数组,用于递归
        nums.forEach(e => {
            if ('' + e + p[0] > '' + p[0] + e) {  //大于基准的,放右边
                R.push(e)
            } else if('' + e + p[0] < '' + p[0] + e){ //小于基准的,放左边
                L.push(e)
            }else{         //等于基准的,放到基准里,这就是p[0]的由来
                p.push(e)
            }
        })
        // 现在让左边,右边去递归。最后按左 中 右 将数组拼接一下即可
        return quicksort(L).concat(p).concat(quicksort(R))
    }
};