堆的操作 及对应题目
一、堆的基本操作
以大根堆为例
包括——初始化堆、调整堆、插入元素和删除元素
对应时间复杂度为O(n)(自底向上建堆),O(logn),O(logn),O(logn)
插入操作:先将新元素添加到堆的末尾;如果它比父节点更大则交换,直到更小。
删除操作是:把堆顶和堆底元素交换,然后再调整[堆顶,堆底前一个元素间]所有元素为一个新的堆
1.1 堆排序:
- 首先将无序序列构造成大根堆——堆顶元素为最大值
- 输出堆顶元素后,将剩余元素调整为新的堆,再输出堆顶。
1.2 “找数组中的第K个最大元素”
对于下标从1开始的数组这样是对的:
class Solution {
public:
//学会用桶排 和 基于快排的方法来做
//使[start,end]成为大根堆
void HeapAdjust(vector<int>& nums,int start,int end){
int temp = nums[start];//待会有可能交换
for(int i=2*start;i<=end;i*=2){
if(i < end && nums[i]<nums[i+1])
i++;
if(nums[i] <= temp)break;//根节点大于子节点,不必调节
//否则
nums[start] = nums[i];
start = i;
}
nums[start] = temp;
}
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
//自下而上建堆法
for(int i = n/2-1; i>=0; i--){
HeapAdjust(nums,i,n-1);//[n-1]是最后一个节点
}
//做 k−1 次删除操作后堆顶元素就是我们要找的答案
for(int i = n-1; i>n-k ; i--){//n-1 - (k-1) = n-k
swap(nums[0],nums[i]);//堆顶和当前未排序子序列最后一记录交换
HeapAdjust(nums,0,i-1);//对[0,i-1]调整为大根堆
}
return nums[0];
}
};
但对于下标从0开始的,应该修改:
//自下而上建堆法
for(int i = n/2-1; i>=0; i--){
HeapAdjust(nums,i,n-1);//[n-1]是最后一个节点
}
//使[start,end]成为大根堆
void HeapAdjust(vector<int>& nums,int start,int end){
int temp = nums[start];//待会有可能交换
for(int i=2*start+1;i<=end;i=2*i+1){
优先队列实现堆
参考自己的这篇文章(含题目“前K个高频元素”)
https://www.cnblogs.com/neromegumi/p/18515471
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架