当前位置: 首页 > article >正文

对顶堆简介 → 第K大问题 + topK问题

【对顶堆】
对顶堆由一个
大根堆G和一个小根堆L构成,且常以小根堆L的堆顶元素L.top()作为对顶堆的分界点,并满足G.top()<L.top()。 换句话表述,就是“在对顶堆中,大根堆的元素都小于L.top(),小根堆的元素都大于L.top()”。显然,若输入的元素大于L.top(),就加入小根堆。反之,就加入大根堆。 对顶堆常见的示意图如右所示。

由于堆常借助于STL中的 priority_queue<int> 来实现,那么对顶堆便可利用 priority_queue<int> 同时声明一个大根堆G及一个小根堆L来实现。对顶堆代码如下所示:

priority_queue<int> G;    //大根堆  
priority_queue<int,vector<int>,greater<int> > L;    //小根堆

【对顶堆 → 第K大问题】
对顶堆常用于求解“
第K小元素”及“第K大元素”问题。因为优先队列priority_queue虽然不像数组那样支持随机访问,但它可以用O(1)的时间查询出堆顶元素。显然,利用对顶堆查询堆顶元素的时间复杂度与数组的随机访问的时间复杂度O(1)持平。特别是当遇到多次动态查询问题时,对顶堆就更高效。此外,对顶堆还可用于解决其他“第K小元素”及“第K大元素”问题的变形问题,如求前n个元素的中位数等问题。
求解“第 K 大元素”问题的解题思路为:若求第 K 大的元素,先利用输入序列提供的前 K 个元素构建一个包括 K 个元素的小根堆 L,后来的元素 x 先与小根堆 L 的堆顶元素 L.top() 比较,如果 x<L.top(),则将 x 加入大根堆 G;否则,将小根堆 L 的堆顶元素 L.top() 弹出后,将 x 加入小根堆 L。当然,
简洁设计方案是利用输入序列提供的前 K 个元素构建一个包括 K 个元素的小根堆 L,便可求解“第 K 大元素”问题。
“第 K 大元素”问题的代码如下所示。

#include<bits/stdc++.h>
using namespace std;

priority_queue<int,vector<int>,greater<int> > L; //Small Root Heap
priority_queue<int> G; //Big Root Heap

int main() {
    int n,k,x;
    cin>>n>>k;
    while(n--) {
        cin>>x;
        if(L.size()<k) L.push(x);
        else if(x>L.top()) {
            G.push(L.top()); //Optional
            L.pop();
            L.push(x);
        }
    }
    cout<<L.top()<<endl;

    return 0;
}

【topK问题】
topK 问题”指从包含 ‌n 个元素的数据集‌中高效获取前 K 个最大或最小元素‌的算法问题,常见于排行榜、实时数据筛选等场景(如百万用户中筛选前100名活跃用户)‌。topK问题可以利用对顶堆来求解。
“topK 问题”问题的代码如下所示。

#include<bits/stdc++.h>
using namespace std;

priority_queue<int,vector<int>,greater<int> > L; //Small Root Heap
priority_queue<int> G; //Big Root Heap

int main() {
    int n,k,x;
    cin>>n>>k;
    while(n--) {
        cin>>x;
        if(L.size()<k) L.push(x);
        else if(x>L.top()) {
            G.push(L.top()); //Optional
            L.pop();
            L.push(x);
        }
    }

    while(!L.empty()) {
        cout<<L.top()<<" ";
        L.pop();
    }

    return 0;
}

显见,“topK”问题的代码与“第K大元素”问题的代码差别极小。
只需将语句 cout<<L.top()<<" "; 修改为如下语句即可。

while(!L.empty()) {
    cout<<L.top()<<" ";
    L.pop();
}










 


http://www.kler.cn/a/597422.html

相关文章:

  • 【STM32实物】基于STM32的扫地机器人/小车控制系统设计
  • vulhub/Web Machine(N7)靶机----练习攻略
  • FPGA-DE2115开发板实现流水灯
  • Android Window浮窗UI组件使用JetPack
  • 小程序多语言
  • 基于深度学习的医学影像分割:从理论到实践
  • 计算机考研-数据结构2.2
  • 爬虫——将数据保存到MongoDB中
  • Vue 双向数据绑定是什么
  • STM32原理性知识
  • 《深入剖析鸿蒙生态原生应用:一次开发多端部署的技术革新》
  • 【数学建模】Lingo 18.0及其安装教程(保姆级)
  • 【Qt】自定义委托(Delegate)的核心方法
  • 基于Netty实现高性能HTTP服务的架构解析
  • Apache APISIX 架构浅析
  • 如何解决 PHP 运行时错误导致的服务中断
  • 网页性能优化中 有一条叫做“避免使用未合成的动画”,请问该如何理解?
  • vim在连续多行行首插入相同的字符
  • 同旺科技USB to I2C 适配器 ---- 指令之间延时功能
  • 【项目设计】网页版五子棋