📌  相关文章
📜  数组中的 k 个最大(或最小)元素 |添加了最小堆方法(1)

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

数组中的 k 个最大(或最小)元素 |添加了最小堆方法

介绍

在开发过程中很常见的一个需求是需要在一个数组中找到最大(或最小)的 k 个元素,这时需要用到一些高效的算法,以减少时间复杂度。本文将介绍如何使用最小堆方法实现该需求。

最小堆

最小堆是一种二叉堆,它满足以下两个条件:

  1. 父节点的值小于或等于其左右子节点的值;
  2. 是一颗完全二叉树。

最小堆的根节点是其中最小的元素,因此也被称为最小优先队列。当我们将元素插入最小堆时,它会自动保持堆的结构,从而使得根节点始终是最小元素。相应地,当我们删除根节点时,最小堆会自动将下一个最小元素移到根节点处,保持堆的结构不变。

如何使用最小堆找到数组中的 k 个最大元素

假设我们要找到数组中的 k 个最大元素,我们可以先将前 k 个元素插入到一个大小为 k 的最小堆中。这时,最小堆的根节点就是 k 个元素中的最小值。

接着,我们可以依次遍历数组中的剩余元素,并将它们与最小堆中的根节点比较。如果该元素大于根节点,则将根节点弹出,将该元素插入到最小堆中。这样,我们就可以保证最小堆中始终只有当前数组前 k 个最大元素,并且根节点始终是其中最小的元素。

当我们遍历完整个数组后,最小堆中的元素就是我们要找的 k 个最大元素。

代码示例

下面是一个使用最小堆方法找到数组中 k 个最大元素的 Java 代码示例:

public static int[] findKthLargest(int[] nums, int k) {
    PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);

    for (int i = 0; i < k; i++) {
        minHeap.offer(nums[i]);
    }

    for (int i = k; i < nums.length; i++) {
        if (nums[i] > minHeap.peek()) {
            minHeap.poll();
            minHeap.offer(nums[i]);
        }
    }

    int[] res = new int[k];
    for (int i = 0; i < k; i++) {
        res[i] = minHeap.poll();
    }

    return res;
}

这个方法的时间复杂度是 O(nlogk),因为它需要将前 k 个元素插入到最小堆中,每次插入的时间复杂度是 O(logk)。接下来,它需要遍历数组中剩余的元素 n-k 次,每次需要比较元素和根节点的大小、弹出根节点、插入新元素等操作,每次操作时间复杂度都是 O(logk)。因此,整个算法的时间复杂度是 O(nlogk)。

结论

以上就是使用最小堆方法找到数组中 k 个最大(或最小)元素的实现方法。这种方法不仅简单易懂,而且时间复杂度比较低,非常适用于大数据量的情况。