数字拼接成最大数的总结
参考
- csdn:几个数拼接生成最大数(java实现)
- csdn:算法题:给出一组数字,拼接一个最大的值
题目:
给定一个数组,例如:[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);
}());