📅  最后修改于: 2023-12-03 15:08:14.112000             🧑  作者: Mango
在 JavaScript 中,有时候我们需要从一个数组中获取最大的元素,或者获取前 n 个最大的元素。下面就介绍几种常见的方法。
可以先对数组进行排序,然后再返回前 n 个最大的元素即可。
function getTopN(arr, n) {
let len = arr.length;
if (n >= len) {
return arr.sort((a, b) => b - a);
} else {
return arr.sort((a, b) => b - a).slice(0, n);
}
}
let arr = [1, 4, 2, 5, 3];
let topN = getTopN(arr, 3);
console.log(topN); // [5, 4, 3]
可以利用快排思路来找到前 n 个最大的元素。首先找到一个 pivot,并将数组分为两部分,一部分是小于 pivot 的,一部分是大于 pivot 的。如果小于 pivot 的数量大于等于 n,则递归处理小于 pivot 的那部分数组;否则,将小于 pivot 的数组全部加入结果数组中,再递归处理大于 pivot 的那部分数组。
function getTopN(arr, n) {
function quickSelect(arr, left, right, n) {
if (left === right) {
return arr[left];
}
let pivotIndex = Math.floor(Math.random() * (right - left + 1)) + left;
pivotIndex = partition(arr, left, right, pivotIndex);
if (n === pivotIndex) {
return arr[n];
} else if (n < pivotIndex) {
return quickSelect(arr, left, pivotIndex - 1, n);
} else {
return quickSelect(arr, pivotIndex + 1, right, n);
}
}
function partition(arr, left, right, pivotIndex) {
let pivotValue = arr[pivotIndex];
swap(arr, pivotIndex, right);
let storeIndex = left;
for (let i = left; i < right; i++) {
if (arr[i] > pivotValue) {
swap(arr, i, storeIndex);
storeIndex++;
}
}
swap(arr, right, storeIndex);
return storeIndex;
}
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
let len = arr.length;
let topN = [];
if (n >= len) {
topN = arr.sort((a, b) => b - a);
} else {
let pivot = quickSelect(arr, 0, len - 1, n);
let smallArr = [];
let largeArr = [];
for (let i = 0; i < len; i++) {
if (arr[i] > pivot) {
smallArr.push(arr[i]);
} else {
largeArr.push(arr[i]);
}
}
if (smallArr.length >= n) {
topN = getTopN(smallArr, n);
} else {
topN = smallArr.concat(getTopN(largeArr, n - smallArr.length));
}
}
return topN.slice(0, n);
}
let arr = [1, 4, 2, 5, 3];
let topN = getTopN(arr, 3);
console.log(topN); // [5, 4, 3]
使用堆排序可以更快地找到前 n 个最大的元素。首先将数组中前 n 个元素建立最小堆,然后遍历剩余的元素,如果大于堆顶元素,则用该元素替换堆顶元素,并调整堆。
function getTopN(arr, n) {
function createHeap(arr, n) {
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
heapify(arr, n, i);
}
}
function heapify(arr, n, i) {
let smallest = i;
let left = i * 2 + 1;
let right = i * 2 + 2;
if (left < n && arr[left] < arr[smallest]) {
smallest = left;
}
if (right < n && arr[right] < arr[smallest]) {
smallest = right;
}
if (smallest !== i) {
swap(arr, i, smallest);
heapify(arr, n, smallest);
}
}
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
let len = arr.length;
let topN = [];
if (n >= len) {
topN = arr.sort((a, b) => b - a);
} else {
topN = arr.slice(0, n);
createHeap(topN, n);
for (let i = n; i < len; i++) {
if (arr[i] > topN[0]) {
topN[0] = arr[i];
heapify(topN, n, 0);
}
}
}
return topN;
}
let arr = [1, 4, 2, 5, 3];
let topN = getTopN(arr, 3);
console.log(topN); // [5, 4, 3]
以上就是三种常见的从 JavaScript 中的数组中获取前 n 个最大元素的方法。不同的方法适用于不同的场景,可以根据实际需要来选择。