热题100_20230510
215、数组中的第K个最大元素(堆排序,优先队列)
题目说明
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
解题思路1:优先队列
直接利用Java内置的PriorityQueue
进行排序处理,保证构造的优先队列是含有k个元素的且从队列尾部到头部从大到小排序(保证priorityQueue.peek()是队列中的最小值),反复用这个元素去和数组的其他元素进行比较判定是否需要替换新的元素进去。最终返回的priorityQueue.peek()即为第K大元素
在构造PriorityQueue
时要new PriorityQueue<Integer>(k, (a, b) -> a - b)
保证队头是最小的(小顶堆)
解题思路2:堆排序
其实就是优先队列的一个底层实现,不过我们仍然要学习堆排序,这很重要!
大根堆:每个节点的值都大于或者等于他的左右孩子节点的值。小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值
堆排序算法步骤:
- 把无序数组构建成为二叉堆(从上到下从左到右构建就好了)
- 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。
void HeapAdjust(int* arr, int start, int end)
{
int tmp = arr[start];
for (int i = 2 * start + 1; i <= end; i = i * 2 + 1)
{
if (i < end&& arr[i] < arr[i + 1])//有右孩子并且左孩子小于右孩子
{
i++;
}//i一定是左右孩子的最大值
if (arr[i] > tmp)
{
arr[start] = arr[i];
start = i;
}
else
{
break;
}
}
arr[start] = tmp;
}
void HeapSort(int* arr, int len)
{
//第一次建立大根堆,从后往前依次调整
for(int i=(len-1-1)/2;i>=0;i--)
{
HeapAdjust(arr, i, len - 1);
}
//每次将根和待排序的最后一次交换,然后在调整
int tmp;
for (int i = 0; i < len - 1; i++)
{
tmp = arr[0];
arr[0] = arr[len - 1-i];
arr[len - 1 - i] = tmp;
HeapAdjust(arr, 0, len - 1-i- 1);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)