📜  如何从 JavaScript 中的数组中获取 n 个最大元素?(1)

📅  最后修改于: 2023-12-03 15:08:14.112000             🧑  作者: Mango

如何从 JavaScript 中的数组中获取 n 个最大元素?

在 JavaScript 中,有时候我们需要从一个数组中获取最大的元素,或者获取前 n 个最大的元素。下面就介绍几种常见的方法。

1. 利用 sort 排序方法

可以先对数组进行排序,然后再返回前 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]
2. 利用快排思路

可以利用快排思路来找到前 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]
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 个最大元素的方法。不同的方法适用于不同的场景,可以根据实际需要来选择。