📜  K 最大元素堆 (1)

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

K 最大元素堆

K 最大元素堆是一种可以维护最大的 k 个元素的数据结构,它可以用来解决诸如查找前 k 大元素等经典问题。在本文中,我们将介绍 K 最大元素堆的实现方式和常见应用场景。

实现方式

K 最大元素堆通常基于优先队列实现。在实现中,我们使用一个大小为 k 的堆来存储当前最大的 k 个元素。当有新元素加入时,我们先判断该元素是否比堆中最小的元素还小,如果是,则直接忽略,否则,我们将该元素加入堆中,并将堆中最小的元素删除。

在实现 K 最大元素堆时,我们可以使用 C++ STL 中的 priority_queue 类来实现。priority_queue 类是一个优先队列,它按顺序存储元素,并可以在队列顶部提取最高优先级的元素。

#include <queue>
#include <vector>

using namespace std;

class KthLargest {
public:
    KthLargest(int k, vector<int>& nums) {
        capacity_ = k;
        for (auto num : nums) {
            add(num);
        }
    }
    
    int add(int val) {
        if (min_heap_.size() < capacity_) {
            min_heap_.push(val);
        } else if (val > min_heap_.top()) {
            min_heap_.pop();
            min_heap_.push(val);
        }
        return min_heap_.top();
    }

private:
    int capacity_;
    priority_queue<int, vector<int>, greater<int>> min_heap_;
};
应用场景

K 最大元素堆有许多实际应用场景,这里介绍其中的两个:

查找前 k 大元素

在面试题中,经常会遇到需要在数组中查找前 k 大元素的问题。我们可以使用 K 最大元素堆来解决该问题,只需要遍历一遍数组,将元素加入 K 最大元素堆中即可。

vector<int> find_top_k_elements(vector<int>& nums, int k) {
    KthLargest kth_largest(k, nums);
    vector<int> top_k_elements;
    for (auto num : nums) {
        top_k_elements.push_back(kth_largest.add(num));
    }
    return top_k_elements;
}
寻找滑动窗口中的最大值

在许多算法问题中,我们需要同时查找一个长度为 k 的滑动窗口中的最大值。如果我们每次都遍历整个窗口,那么时间复杂度将为 $O(nk)$。但是如果我们使用 K 最大元素堆,那么每次将堆中 k 个元素进行比较即可,时间复杂度为 $O(nlogk)$。

vector<int> find_max_sliding_window(vector<int>& nums, int k) {
    KthLargest kth_largest(k, nums);
    vector<int> max_sliding_window;
    for (int i = k; i <= nums.size(); ++i) {
        max_sliding_window.push_back(kth_largest.add(nums[i]));
    }
    return max_sliding_window;
}
总结

K 最大元素堆是一种可以在常数时间内维护最大的 k 个元素的数据结构,它通常基于优先队列实现。它可以用来解决诸如查找前 k 大元素、寻找滑动窗口中的最大值等经典问题。