热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LeetCode笔记:剑指Offer41.数据流中的中位数(Java、堆、优先队列、知识点)

本文介绍了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;/** initialize your data structure here. */public MedianFinder() {// 各存一半&#xff1a;small 小顶堆存储较大部分&#xff1b;big 大顶堆存储较小部分smallHeap &#61; new PriorityQueue<>();bigHeap &#61; new PriorityQueue<>((x, y) -> (y - x));}// 维护两个 Heap 的较大、较小属性&#xff1a;O(logn)public void addNum(int num) {// N &#61; 奇数&#xff1a;增加 bigHeap 元素&#xff0c;通过先添加到 smallHeap&#xff0c;再获取其堆顶实现if(smallHeap.size() !&#61; bigHeap.size()) {smallHeap.add(num);bigHeap.add(smallHeap.poll());} // N &#61; 偶数&#xff1a;增加 small 元素&#xff0c;通过先添加到 bigHeap&#xff0c;再获取其堆顶实现else {bigHeap.add(num);smallHeap.add(bigHeap.poll());}}// O(1)public double findMedian() {// 偶数情况if(smallHeap.size() &#61;&#61; bigHeap.size()) {// 较大堆的最小值 &#43; 较小堆里的最大值return (smallHeap.peek() &#43; bigHeap.peek()) / 2.0;}// 奇数情况else {return smallHeap.peek();}}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj &#61; new MedianFinder();* obj.addNum(num);* double param_2 &#61; obj.findMedian();*/

二刷


  • 关键词&#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();}}
}

推荐阅读
  • 本文提供了使用Java实现Bellman-Ford算法解决POJ 3259问题的代码示例,详细解释了如何通过该算法检测负权环来判断时间旅行的可能性。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 深入解析for与foreach遍历集合时的性能差异
    本文将详细探讨for循环和foreach(迭代器)在遍历集合时的性能差异,并通过实际代码示例和源码分析,帮助读者理解这两种遍历方式的不同之处。文章内容丰富且专业,旨在为编程爱好者提供有价值的参考。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
author-avatar
用户tbz3kln7yj
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有