note_16:数字拼接成最大数

本文探讨了将一数组中的数字拼接成最大可能数值的算法。通过对比两个数字拼接后的大小,重新排序数组,最终形成最大数。介绍了三种方法,包括简单的排序和拼接,基于比较的排序,以及全排列比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数字拼接成最大数的总结


参考


题目:

给定一个数组,例如:[12, 435, 8, 49, 82, 2],拼出一个最大数88249435212。

思路:

比较的时候把两个数字拼在一起,排两个顺序。例如:80和82,排出8082和8280。因为8082 < 8280,所以82要放在80前面。

网上的方法是这样的:

function func(numArr) {
  var str = "";
  for (var i = 0; i < numArr.length; i++) {
    for (var j = i + 1; j < numArr.length; j++) {
      if (cmp(numArr[i], numArr[j])) {
        var temp = numArr[j];
        numArr[j] = numArr[i];
        numArr[i] = temp;
      }
    }
  }
  for (var k = 0; k < numArr.length; k++) {
    str += numArr[k].toString();
  }
  console.log(str); // 88249435212
}

function cmp(a, b) {
  var s1 = a.toString() + b.toString();
  var s2 = b.toString() + a.toString();
  for (var i = 0; i < s1.length; i++) {
    if (s1.substr(i, 1) < s2.substr(i, 1)) {  // 第一个数比第二个数小,要放后面
      return true;
    } else if (s1.substr(i, 1) > s2.substr(i, 1)) { // 第一个数比第二个数大,要放前面
      return false;
    }
  }
  return false; // 如果两个数相等
}

(function main() {
  var numArr = [12, 435, 8, 49, 82, 2];
  func(numArr);
}());

自白:

  • 最初的思路是,每个数的第一位拿出来比较,如果是最大的就直接拿出来。可是忽略了两个数的第一位相同的情况。
  • 第二次是想,如果两个数的第一位相同,那么就在位数不够的那个数后面补0,然后把值小的那个选出来。但是,如果给出的数组是80,82,补0的方法就不对了。

因为不想完全抄网上的方法,也就是不想完全放弃自己的想法,所以就写成了这样。其实都是一样的。

function func(numArr) {
  var str = "";
  while (numArr.length !== 0) {
    var head = numArr.shift();
    var max = head;
    var pos = -1;
    for (var i = 0; i < numArr.length; i++) {
      var first = max.toString();
      var second = numArr[i].toString();
      var s1 = parseInt(first + second);
      var s2 = parseInt(second + first);
      if (s1 < s2) {
        max = numArr[i];
        pos = i;
      }
    }
    str += max.toString();
    if (pos != -1) {
      numArr.push(head);
      numArr.splice(pos, 1);
    }
  }
  console.log(str);  // 88249435212
}

(function main() {
  var numArr = [12, 435, 8, 49, 82, 2];
  func(numArr);
}());

自白:

  • 后来想过换方法,就是把数字全部组合一次,然后选出最大的字符串,但是那样的话时间复杂度是 O ( n ! ) O(n!) O(n!)。而上面的方法的时间复杂度是 O ( n 2 ) O(n^2) O(n2)

如果是把所有的数字都拼一次字符,代码是这样的,不过肯定会有比这份更简洁的代码。

function func(numArr) {
  var max = "0";
  var queue = [];
  for (var j = 0; j < numArr.length; j++) {
    var temp = [];
    temp.push(numArr[j]);
    queue.push(temp);
  }
  var element = [];
  while (queue.length !== 0) {
    var head = queue.shift();
    for (var i = 0; i < numArr.length; i++) {
     
       var flag = false;  // 因为数字只贴一次就好了,所以不能让它重复贴
       for (j = 0; j < head.length; j++) {
           if (head[j] == numArr[i]) {
             flag = true;
             break;
           }
       }
       if (flag) {
         continue;
       }
        
       var first = "";
       for (j = 0; j < head.length; j++) { // 如果直接用join()的话会有逗号
         first += head[j].toString();      // 要用replace()处理继续处理
       }
       var second = numArr[i].toString();
       var str = first + second;
       if (head.length + 1 == numArr.length) { // 如果已经拼完了所有数字,就不再push()了
         if (parseInt(str) > parseInt(max)) {
           max = str;
         }
       } else {
         element = [];
         for (j = 0; j < head.length; j++) {
           element.push(head[j]);
         }
         element.push(numArr[i]);
         queue.push(element);
       }
     }
  }
  console.log(max);  // 88249435212
}

(function main() {
  var numArr = [12, 435, 8, 49, 82, 2];
  func(numArr);
}());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值