算法------(10)堆

例题:(1)AcWing 838. 堆排序

        我们可以利用一个一维数组来模拟堆。由于堆本质上是一个完全二叉树,他的每个父节点的权值都小于左右子节点,而每个父节点编号为n时,左节点编号为2*n,右节点编号为2*n+1。用size记录堆的大小便于维护。在初始建立堆时,由于最后一层在前面每一层建立后自然而然就会被排序,因此我们只需要从倒数第二层开始建立到第一层即可。建立的过程利用到down操作,down操作本质上就是在父节点和两个子节点中进行比较换位,直到往下也不需要换位。而由于一维数组不方便删除头结点,但是删除尾节点只需要size--,因此我们删除头节点的操作就是把头结点和尾结点交换,然后把新的头节点down。 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int heap[N],sz;
void down(int u){int t = u;if(u*2<=sz&&heap[u*2] < heap[t]) t = u*2;if(u*2+1<=sz&&heap[u*2+1] < heap[t]) t = u*2+1;if(t!=u){swap(heap[t],heap[u]);down(t);}
}
int main()
{int n,m;scanf("%d%d", &n, &m);for(int i = 1;i<=n;i++){scanf("%d", &heap[i]);}sz = n;for(int i = n/2;i;i--){down(i);}while(m--){printf("%d ",heap[1]);heap[1] = heap[sz--];down(1);}return 0;
}

(2)AcWing 839. 模拟堆  

        模拟堆的过程相比上面多了几个操作:(1)删除第k个数,修改第k个插入的数,需要用一个记录下标-第k个插入的数和相反关系的两个数组进行维护。(2)还需要用up把下面的较小数往上移。 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
unordered_map<int,int> id,mp;//id的对应关系:下标-第k个插入的数,mp的对应关系: 第k个插入的数 - 下标 
int h[N];
int sz,cnt;
void down(int u){int t = u;if(u*2<=sz&&h[u*2]<h[t]) t = u*2;if(u*2+1<=sz&&h[u*2+1]<h[t]) t = u*2+1;if(t!=u){swap(mp[id[u]],mp[id[t]]);swap(id[u],id[t]);swap(h[u],h[t]);down(t);}
}
void up(int u){int t = u;if(u/2&&h[u/2]>h[t]) t = u/2;if(t!=u){swap(mp[id[u/2]],mp[id[u]]);swap(id[u/2],id[u]);swap(h[u/2],h[u]);up(t);}
}
int main()
{int n;scanf("%d", &n);for(int i = 0;i<n;i++){char op[5];scanf("%s",op);if(!strcmp(op,"I")){int x;scanf("%d", &x);h[++sz] = x;mp[++cnt] = sz;id[sz] = cnt;up(sz);}else if(!strcmp(op,"PM")){printf("%d\n",h[1]);}else if(!strcmp(op,"DM")){swap(mp[id[1]],mp[id[sz]]);swap(id[1],id[sz]);swap(h[1],h[sz]);sz--;down(1);}else if(!strcmp(op,"D")){int k;scanf("%d", &k);k = mp[k];swap(mp[id[k]],mp[id[sz]]);swap(id[k],id[sz]);swap(h[k],h[sz]);sz--;down(k);up(k);}else{int x,k;scanf("%d%d", &k, &x);k = mp[k];h[k] = x;down(k);up(k);}}return 0;
}

练习:(1)Leetcode 692.前k个高频单词         没做出来。。优先队列居然还能这么用的吗。。

         先用哈希表统计每个单词出现的次数,然后遍历哈希表(可以用auto直接循环),把每个<string,pair>加入到优先队列进行排序。最后由于需要按照字典序排序,我们还需要从后往前放置答案。

class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {unordered_map<string,int> x;for(auto c:words){x[c]++;}auto cmp = [](const pair<string,int> &a,pair<string,int> &b){return a.second == b.second ? a.first < b.first : a.second > b.second;};priority_queue<pair<string,int>,vector<pair<string,int>>, decltype(cmp)> ans(cmp);for(auto c:x){ans.push(c);if(ans.size()>k) ans.pop();}vector<string> res(k);for(int i = k-1;i>=0;i--){res[i]=ans.top().first;ans.pop();}return res;}
};

(2)Leettcode 703.数据流中的第K大元素 

        一开始一直想靠sort。。没用。。

        由于优先队列只能访问队头数组,所以我们要让数据流中的第K大元素是优先队列的队头,因此我们要保证优先队列中只有K个数,这K个数中的最小的数就一定是第K大的数,也是优先队列的队头。

class KthLargest {
public:priority_queue<int,vector<int>,greater<int>> x;int k;KthLargest(int k, vector<int>& nums) {this->k = k;for(auto c:nums){x.push(c);if(x.size()>k) x.pop();}}int add(int val) {x.push(val);if(x.size()>k) x.pop();return x.top();}
};

(3) Leetcode 264.丑数II

        

        没做出来。。

        假如一个数为丑数,那么这个数的两倍,三倍和五倍对应的数也是丑数,当然这么做肯定会有重复,因此我们用一个哈希集合来存储出现过的数,这样保证小根堆里面不出现重复的数,因此第k次取出来的数就是第k个丑数。

class Solution {
public:long nthUglyNumber(int n) {priority_queue<long,vector<long>,greater<long>> x;unordered_set<int> y;x.push(1);y.insert(1);for(int i = 0;i<n-1;i++){long k = x.top();x.pop();if(!y.count(k*2)){x.push(k*2);y.insert(k*2);}if(!y.count(k*3)){x.push(k*3);y.insert(k*3);}if(!y.count(k*5)){x.push(k*5);y.insert(k*5);}}return x.top();}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/433323.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为参与打造的中医药大模型问世

快科技消息&#xff0c;华为中国官微发文称&#xff0c;浙江九为健康科技股份有限公司与华为云计算技术有限公司在深圳签署大模型全面深化合作协议。 通过整合九为健康在中医药领域的专业能力与华为云在AI大模型领域的技术优势&#xff0c;双方就市场推广、生态合作、人工智能联…

kafka summary

最近整体梳理之前用到的一些东西&#xff0c;回顾Kafka的时候好多东西都忘记了&#xff0c;把一些自己记的比较模糊并且感觉有用的东西整理一遍并且记忆一遍&#xff0c;仅用于记录以备后续回顾 Kafka的哪些场景中使用了零拷贝 生产者发送消息&#xff1a;在 Kafka 生产者发送…

代码随想录算法训练营第十七天|110 平衡二叉树、257 二叉树的所有路径、404 左子叶之和

110 平衡二叉树 题目链接&#xff1a;平衡二叉树 思路 首先要明确下二叉树的高度和深度&#xff0c;高度是从叶节点开始&#xff0c;深度则是从根节点开始的。在104 二叉树的最大深度的那道题目中&#xff0c;树的深度和根节点的高度相等&#xff0c;所以使用了后序遍历。 这…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 1月27日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年1月27日 星期六 农历腊月十七 1、 住建部&#xff1a;充分赋予城市房地产调控自主权&#xff0c;各城市可以因地制宜调整房地产政策。 2、 公安部&#xff1a;户口迁移等多项高频户籍业务实现全国“跨省通办”。 3、 环…

修复idea,eclipse ,clion控制台中文乱码

控制台乱码问题主要原因并不在编译器IDE身上&#xff0c;还主要是Windows的控制台默认编码问题。。。 Powershell&#xff0c;cmd等默认编码可能不是UTF-8&#xff0c;无需改动IDE的settings或者properties&#xff08;这治标不治本&#xff09;&#xff0c;直接让Windows系统…

GitBook可以搭建知识库吗?有无其他更好更方便的?

在一个现代化的企业中&#xff0c;知识是一项宝贵的资产。拥有一个完善的企业知识库&#xff0c;不仅可以加速员工的学习和成长&#xff0c;还能提高工作效率和团队协作能力。然而&#xff0c;随着企业不断发展和扩大规模&#xff0c;知识库的构建和管理变得更加复杂和耗时。 |…

第二百八十八回

文章目录 1. 概念介绍2. 使用方法2.1 实现步骤2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取文件类型"相关的内容&#xff0c;本章回中将介绍如何播放视频.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 播放视频是我们常用…

如何在Shopee平台上进行宠物类目的选品丨shopee宠物选品

在Shopee平台上进行宠物类目的选品是一个重要的任务&#xff0c;它直接关系到卖家的销售业绩和市场竞争力。为了成功选择适合的宠物用品&#xff0c;在选品过程中&#xff0c;卖家可以遵循以下策略&#xff1a; 先给大家推荐一款shopee知虾数据运营工具知虾免费体验地址&#…

Nodejs前端学习Day1_补档

我给day1搞没了&#xff0c;还是觉得该补一个&#xff0c;有用 文章目录 前言一、学习目标二、学习目录三、为什么JavaScript代码可以在浏览器中运行四、为什么JavaScript可以操作DOM和BOM五、浏览器中的JavaScript运行环境总结 前言 补档 一、学习目标 二、学习目录 三、为什…

MySql8的简单使用(1.模糊查询 2.group by 分组 having过滤 3.JSON字段的实践)

MySql8的简单使用&#xff08;1.模糊查询 2.group by 分组 having过滤 3.JSON字段的实践&#xff09; 一.like模糊查询、group by 分组 having 过滤 建表语句 create table student(id int PRIMARY KEY,name char(10),age int,sex char(5)); alter table student add height…

React中使用LazyBuilder实现页面懒加载方法二

前言&#xff1a; 在一个表格中&#xff0c;需要展示100条数据&#xff0c;当每条数据里面需要承载的内容很多&#xff0c;需要渲染的元素也很多的时候&#xff0c;容易造成页面加载的速度很慢&#xff0c;不能给用户提供很好的体验时&#xff0c;懒加载是优化页面加载速度的方…

Dynamic-Pix2Pix:改进 Pix2Pix 在有限的训练数据下性能问题

Dynamic-Pix2Pix&#xff1a;改进 Pix2Pix 在有限的训练数据下性能问题 核心思想Dynamic-Pix2Pix 网络结构效果总结 核心思想 论文&#xff1a;https://arxiv.org/ftp/arxiv/papers/2211/2211.08570.pdf 代码&#xff1a;https://github.com/pranoyr/dynamic-Pix2Pix.git 如…