图片来源自网络,侵删~
堆是一棵顺序存储的完全二叉树。
- 其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小顶堆。
- 其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大顶堆。
该逻辑映射到数组中:
设当前元素在数组中以R[i]表示,那么,
(1) 它的左孩子结点是:R[2*i+1];
(2) 它的右孩子结点是:R[2*i+2];
(3) 它的父结点是:R[(i-1)/2];
(4) R[i] <= R[2*i+1] 且 R[i] <= R[2i+2]。
1.数组中的第K个最大元素
1)这道题如果不考虑面试,直接用sort就OK了,sort(num.begint(),num.end(),less<int>())从小到大排序,或者sort(num.begin(),num.end(),greater<int>())从大到小排序;
2)优先队列:
//升序队列,小顶堆
使用小顶堆,如果当前堆长度大于输入的k,则堆顶元素pop,始终保持堆中有k个元素。最后输出top;
class
以上两种方法,怕是面试会被怼。
2.前 K 个高频元素
1)首先利用unordered_map存储每个数字出现的频率;
2)采用小根堆,用优先队列,若队列长队小于k则直接push_back,否则比较出现频率,若小根堆的top元素频率小于新元素,则pop(),将新元素push_back;
3)翻转结果并输出。
class
conclusion: 堆用来解决前k个最大元素、最高频率等问题很好,可以保持堆长度为k,最后直接输出堆的结果即可; 用priority_queue来实现堆很方便。