C++程序 在数据流中查找第k大元素

C++程序 在数据流中查找第k大元素

在处理数据流时,假如需要找到其中第k大的元素,可以使用优先队列(Priority Queue)来处理。在C++中,标准库STL提供了Priority Queue的实现。

什么是Priority Queue

Priority Queue是一种通过 堆(Heap) 来实现的数据结构,它遵循以下规则:

  1. 它是一个有序的序列,每个元素有自己的权值。
  2. 在Priority Queue中,权值最大的元素永远排在最前面(因此也叫最大堆),而权值较小的元素则排在后面。
  3. 当在Priority Queue中插入一个新的元素时,它会自动排序,使得新的元素插入到合适的位置。
  4. 删除Priority Queue中的元素时,它会自动将最大权值的元素弹出(也就是先进先出)。

优先队列的用法

C++中,Priority Queue的定义如下:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

其中,T为Priority Queue中元素的类型,Container则是底层的容器类型,而Compare则是元素间比较的方式。如果不指定Compare,则默认使用std::less。

接下来,我们给出一个简单的例子,演示了在数据流中查找第k大元素的实现方法。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

class KthLargest {
public:
    KthLargest(int k, vector<int>& nums) {
        m_k = k;
        for(auto n : nums) {
            add(n);
        }
    }

    int add(int val) {
        if(m_queue.size() < m_k) {
            m_queue.push(val);
        } else if(val > m_queue.top()) {
            m_queue.pop();
            m_queue.push(val);
        }
        return m_queue.top();
    }
private:
    priority_queue<int, vector<int>, greater<int>> m_queue;
    int m_k;
};

int main() {
    int k = 3;
    vector<int> nums = {4, 5, 8, 2};
    KthLargest kthLargest(3, nums);
    cout << kthLargest.add(3) << endl;   // 返回 4
    cout << kthLargest.add(5) << endl;   // 返回 5
    cout << kthLargest.add(10) << endl;  // 返回 5
    cout << kthLargest.add(9) << endl;   // 返回 8
    cout << kthLargest.add(4) << endl;   // 返回 8

    return 0;
}

在上述例子中,我们定义了一个类KthLargest用于在数据流中查找第k大的元素。类的构造函数中,初始化了m_k表示需要查找的元素的下标,同时通过for循环将nums中的元素依次加入到Priority Queue中。在add函数的实现中,我们采用了以下方法:

  • 如果Priority Queue的大小小于k,直接将元素加入到Priority Queue中。
  • 如果Priority Queue的大小等于k,将新元素和Priority Queue中的最小元素进行比较。
    • 如果新元素较大,将Priority Queue中的最小元素弹出,将新元素加入到Priority Queue中。
    • 如果新元素较小,不进行操作,直接返回Priority Queue中的最小元素。

最终,在main函数中测试时,我们得到了正确的结果。完整的代码可以在本文末尾的github链接查看。

时间复杂度和空间复杂度

在Priority Queue的实现过程中,我们使用到了堆(Heap)的数据结构,每次插入和弹出元素的时间复杂度为O(logN),其中N为Priority Queue中元素的个数。在构造函数中,我们需要将所有元素遍历一遍,因此时间复杂度为O(NlogK),其中K为需要查找的元素的下标。所以,总的时间复杂度为O(NlogK)。

在空间复杂度方面,我们需要使用一个Priority Queue来存储元素,因此空间复杂度为O(K)。

结论

在处理数据流时需要查找第k大的元素,可以使用Priority Queue来实现。在将元素加入Priority Queue时,可以使用类似于快速排序的方法,将小于等于第k大元素的元素都弹出,只保留大于第k大元素的元素。通过这种方式,可以保证Priority Queue中存储的都是大于第k大元素的元素,最后返回Priority Queue中的最小元素即可。在时间复杂度方面,总的时间复杂度为O(NlogK),空间复杂度为O(K)。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

C++ 示例