Лучший алгоритм для выполнения альтернативной сортировки массива с помощью javascript?
Следующий вопрос был моим вопросом. Но я не мог взломать его и даже не мог подумать, как это сделать.
var arr = [1,4,5,8,3,2,6,9,7,10];
Ожидаемый результат альтернативной сортировки:
[10,1,9,2,8,3,7,4,6,5]
То, что я пробовал:
Я попробовал нарезать Math.max.apply(null, arr) и Math.min.apply(null, arr), чтобы вставить отдельный пустой массив. Но было сказано, что алгоритм не является оптимальным.
Ответы
Ответ 1
Вот один из способов сделать это:
var arr = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
// Sort the source array
arr.sort((a, b) => a - b);
// This will be the final result
var result = [];
// Create two pointers
var a = 0,
b = arr.length - 1;
while (result.length < arr.length) {
// Push the elements from start and end to the result array
result.push(arr[b]);
// Avoid bug when array is odd lengthed
if (a !== b) {
result.push(arr[a]);
}
a++;
b--;
}
console.log(result);
Ответ 2
Я бы отсортировал массив, а затем повторил его, выбирая значения с начала и конца (inloop расчетные смещения) на каждой итерации. Окончательная проверка на нечетные массивы завершила бы процесс.
let a = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
a.sort((a, b) => a - b);
let b =[];
let l = a.length-1; // micro optimization
let L = l/2; // micro optimization
for(var i=0; i<L; i++) b.push( a[l-i] ,a[i] );
if(a.length%2) b.push( a[i] ); // add last item in odd arrays
console.log(b);
Ответ 3
Если вы предположите, что массив будет набором последовательных чисел (хороший вопрос, чтобы спросить о данных), вы можете сделать это очень быстро, без необходимости сортировать или мутировать исходный массив (например, O (n)):
var arr = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
let a = arr.reduce((a, c, i) => {
a[c > arr.length >> 1 ? (arr.length - c) << 1 : (c << 1) - 1] = c
return a
}, [])
console.log(a)
Ответ 4
Здесь мой ответ, основанный на интуиции, которую вы берете с фронта, а затем назад, повторно из отсортированного массива, пока не станет пустым. Трюк избегает "max" и "min", которые оценивают весь массив и просто сортируют его один раз.
Многие из других ответов помещают неопределенный в массив, если исходный массив имеет нечетную длину. Я бы оставил комментарий по этим вопросам, но у меня нет репутации. Вот почему я ограничиваю проверку дважды за цикл.
var arr = [1,4,5,8,3,2,6,9,7,10];
// Sort numerically (not lexicographically)
arr.sort((a, b) => a - b)
// The output array
var out = []
// Take from the front, then back until original array is empty
while (true) {
if (arr.length == 0) break
out.push(arr.pop())
if (arr.length == 0) break
out.push(arr.shift())
}
// Output answer
console.log(out)
Ответ 5
Мое решение для удобочитаемости/скрытой магии:
// Input
var arr = [1,4,5,8,3,2,6,9,7,10];
// Sort
var arr1 = arr.sort((a,b) => (a - b));
// Compose
var arr2 = [];
for (var i = 0; i < arr1.length; i++) {
arr2.push(arr1[(i % 2) === 0
? arr1.length-1-(i/2) // get from end half
: (i-1)/2 // get from begin half
])
}
// Output
console.log(arr2); // = [10, 1, 9, 2, 8, 3, 7, 4, 6, 5]
Ответ 6
Альтернативный метод с добавлением только одной переменной:
var arr = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
arr = arr.sort((a, b) => b - a);
var result = [];
var a = 0;
while (result.length < arr.length) {
result.push(arr[a]);
result.push(arr[arr.length - a - 1]);
a++;
}
console.log(result);
Ответ 7
var a = [1,4,5,8,3,2,6,9,7,10];
var b = a.sort((a, b) => a - b);
var c = a.sort((a, b) => a - b).reverse();
var d = [];
let e = a.length-1;
let f = e/2;
for(let i=0; i<f; i++) d.push( b.pop(), c.pop() );
Замените b и c в цикле for на функции для проверки:
for(let i=0; i<f; i++) d.push( a.sort((a, b) => a - b).pop(), a.sort((a, b) => a - b).reverse().pop() );
Ответ 8
sort
массив и разделите на две части, теперь используйте сокращение, чтобы поместить элементы из двух массивов
//original array
var arr = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
//sorting origina array in ascending order
var m = arr.sort(function(a, b) {
return a - b;
});
// diving the sorted array in two parts
let getFirstSet = m.splice(0, arr.length / 2);
// now m containleft over items after the splice
// again sorted it in descending order to avoid back looping
let getSecondSet = m.sort(function(a, b) {
return b - a;
});
//using reduce function
let newArray = getFirstSet.reduce(function(acc, curr, index) {
// pushing element from second array containing 10,9,8,7,6
acc.push(getSecondSet[index]);
// pushing element from first array containing 1,2,3,4,5
acc.push(getFirstSet[index]);
return acc;
}, []); // [] is the initial array where elements will be pushed
console.log(newArray)
Ответ 9
Другой альтернативный взгляд... если этот фанковый сорт будет сделан на месте, например .sort
?
let input = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
input.sort((a, b) => b - a).every((n, i, a) => (a.splice((i * 2 + 1), 0, a.pop()), (i * 2) < a.length));
console.log(input);
Ответ 10
Вот быстрое решение, использующее тройные операторы и оператор modulo для переключения.
let arr = [1, 4, 5, 8, 3, 2, 6, 9, 7, 10];
let j = 0;
let k = arr.length - 1;
// sort array
arr.sort((a, b) => a - b);
let new_array = [];
for (let i in arr) {
new_array[i] = i % 2 == 0 ? arr[k--] : arr[j++];
}
// prints array
console.log(new_array);