如何对一个数组进行排序,使得最大值位于中间?

7

假设我有一个简单的数组:

[1, 20, 15, 37, 46, 9]

我需要让它看起来像这样:

[1, 9, 15, 46, 37, 20]

因此,这个想法是将最大值或最大的两个值对放在数组的中间,然后像金字塔一样将递减的数字放在其右侧和左侧。

我有一些想法,但它们似乎不够优雅。请给予建议。


这些值是唯一的吗? - VisioN
你的例子中最大的一对不应该是 15, 46,而是 46, 37 吗? - Johan
9个回答

3

试试这个:

var arr = [1, 20, 15, 37, 46, 9];
arr.sort(function (a, b) {
    return a - b;
});
var arr1 = arr.slice(0, arr.length / 2);
var arr2 = arr.slice(arr.length / 2, arr.length);
arr2.sort(function (a, b) {
    return b - a;
});
arr = arr1.concat(arr2);
console.log(arr);

这种方法分为两步:
[1, 20, 15, 37, 46, 9]    // step 1: sort the entire array
[1, 9, 15, 20, 37, 46]    // step 2: sort the second half of the array
[1, 9, 15, 46, 37, 20]

3
var arr = [1,20,15,37,46,9];
arr.sort(function(a,b){
 return a-b;
});
var right = arr.slice(arr.length/2,arr.length).reverse();
var left = arr.slice(0,arr.length/2);
arr = left.concat(right);
console.log(arr);

2

这段代码可以进行优化,但它是可行的。

function pyramid (arr) {
    var newArr = [];

    // sort numerically
    arr.sort(function (a, b) {
        return a - b;
    });

    // put the biggest in new array
    newArr.push(arr.pop());

    // keep grabbing the biggest remaining item and alternate
    // between pushing and unshifting onto the new array
    while (arr.length) {
        newArr[arr.length % 2 === 0 ? 'push' : 'unshift'](arr.pop());
    }

    return newArr;
}

pyramid([1, 20, 15, 37, 46, 9] 返回 [1, 15, 37, 46, 20, 9]


1
我本来也想回答同样的问题:使用push和unshift可以在两侧添加元素,将最大的元素四舍五入。 - Pablo Lozano

1

我无法给你一个JavaScript示例,但我会先将每个数组元素排序,然后枚举(给出索引),然后从前面和后面按偶数/奇数顺序添加它们。

[1, 20, 15, 37, 46, 9]

变成

[1, 9, 15, 20, 37, 46]

然后打印出数组大小一半之前的奇数索引,接着从末尾开始打印下降到一半的偶数索引。
编辑:有趣的Python编程。
tt = sorted([1, 20, 15, 37, 46, 9])
print tt[0:len(tt)/2] + list(reversed(tt[len(tt)/2:len(tt)]))

1
这是另一种简短的链式方法:

[1, 20, 15, 37, 46, 9].sort(function(a, b) {
    return a - b;
}).map(function(v, i, a) {
    var p = ~~(a.length / 2);
    return i >= p ? a[a.length - i + p - 1] : v;
});

// [1, 9, 15, 46, 37, 20]

看起来对于数组中的任意数量的元素都能很好地工作。

+1 对于 ~~ 酷技巧 - reergymerej

1
数组排序、对半分割再拼接的技巧在元素数量增多时效果不佳,其中一侧会比另一侧“更大”。
let arr = [361, 324, 289, 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1, 0];
arr = arr.slice(arr.length/2).reverse().concat(arr.slice(0,arr.length/2));
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 361, 324, 289, 256, 225, 196, 169, 144, 121, 100]

交替排列奇偶索引看起来更好,并且只需要稍微多一点时间。
arr = arr.filter((v, i)=>i % 2 === 0).reverse().concat(arr.filter((v, i)=>i % 2 === 1));
// [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 324, 256, 196, 144, 100, 64, 36, 16, 4, 0]

1

更简单的算法

第一步 - 按降序排列数组并定义一个新的空数组。

第二步 - 遍历排序后的数组,并按以下方式插入其项 - 如果为偶数,将其推入空数组否则将该项插入到开头。

示例

let randoms = [7 ,53 ,21, 43 ,45 ,8, 12, 9, 3, 22, 21]; //some random unsorted array

randoms.sort((a,b) => b - a);   // sorting the array
let sortedFromMiddle = []; //the new empty array

randoms.forEach(( num, index ) => { 
    index % 2 === 0 ? sortedFromMiddle.push(num) : sortedFromMiddle.unshift(num);
  });

console.log(sortedFromMiddle); // will log the array 

0

splice 方法返回一个数组,该数组包含从原始数组中删除的项目-

function pyramid(arr){
    var  mid= Math.floor(arr.length/2);
    var a2= arr.sort(function(a,b){return a-b}).splice(mid);
    return arr.concat(a2.reverse());
}

var a1= [1, 20, 15, 37, 46, 9];
pyramid(a1)

/* 返回值:(数组) 1、9、15、46、37、20 */


-2
var data = [1, 20, 15, 37, 46, 9];
arr = data.sort(function(a, b){return a - b});
console.log(arr);

这将返回 [1, 9, 15, 20, 37, 46]


1
这并没有回答问题。 - ahmdx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接