作者:用户tbz3kln7yj | 来源:互联网 | 2023-12-14 13:34
本文介绍了LeetCode剑指Offer41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。
文章目录
- 题目描述
- 知识点
- 1. 优先队列
- 2. Java 中 queue 的 offer、poll 等区别
- 思路 && 代码
打卡第十一天~
题目描述
- 虽然但是,这是一道很nice的题目(涉及的知识点、运用很实用,见知识点模块)
知识点
1. 优先队列
- priorityQueue 是 Queue 接口的实现,可以对其中元素进行排序。
- 默认顺序是升序;采用的是堆排序(小顶堆),因此只能保证根是最值,整个堆并不是有序的。
- 自定义比较类:在 priorityQueue 的构造函数参数中用 Lambda 表达式表示即可。
2. Java 中 queue 的 offer、poll 等区别
- add、offer:都是添加;队满情况 add 抛出异常,而 offer 则返回 false,可用于判断
- remove、poll:都是删除首元素;队空情况remove抛出异常,而 poll 返回 null
- element、peek:都是查询首元素;队空情况element抛出异常,而peek 返回 null
思路 && 代码
- 代码量不大,主要考察的思路~
- 首先中位数需要考虑总数奇偶情况:奇取中值,偶取平均值。
- 然后既然想获得好的时间复杂度,那就空间换时间了(否则数组慢慢来也行了)
- 接着,既然中位数是在排序后元素集的中间,那么我们可以有这么一个考虑:中间靠两个数据结构实现(毕竟一半一半嘛!),而有序(或局部有序)的数据结构中,进行 add 操作的时间复杂度最低的(O(logn))就是堆了!
- 因此,我们选取优先队列来作为实现的数据结构~
- 主要思路:大顶堆存储较小部分,小顶堆存储较大部分。通过两个堆的堆顶来取中位数。通过先添加到堆a,再添加堆a的堆顶到堆b的“洗元素”方式来维护较大、较小的属性。
class MedianFinder {Queue<Integer> smallHeap, bigHeap;public MedianFinder() {smallHeap &#61; new PriorityQueue<>();bigHeap &#61; new PriorityQueue<>((x, y) -> (y - x));}public void addNum(int num) {if(smallHeap.size() !&#61; bigHeap.size()) {smallHeap.add(num);bigHeap.add(smallHeap.poll());} else {bigHeap.add(num);smallHeap.add(bigHeap.poll());}}public double findMedian() {if(smallHeap.size() &#61;&#61; bigHeap.size()) {return (smallHeap.peek() &#43; bigHeap.peek()) / 2.0;}else {return smallHeap.peek();}}
}
二刷
- 关键词&#xff1a;优先队列、堆之间洗数据、Lambda 表达式
- 思路还是难忘&#xff0c;代码也不多。这道题保持 hard 的时间估计不长了…
class MedianFinder {Queue<Integer> smallTop &#61; new PriorityQueue<>();Queue<Integer> bigTop &#61; new PriorityQueue<>((x, y) -> (y - x));public MedianFinder() {}public void addNum(int num) {if(smallTop.size() &#61;&#61; bigTop.size()) {bigTop.add(num);smallTop.add(bigTop.poll());}else {smallTop.add(num);bigTop.add(smallTop.poll());}}public double findMedian() {if(smallTop.size() &#61;&#61; bigTop.size()) {return (smallTop.peek() &#43; bigTop.peek()) / 2.0;}else {return smallTop.peek();}}
}