热门标签 | 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中的实现方法。二叉堆是一种特殊的完全二叉树,具有堆性质,常用于实现优先队列。 ... [详细]
  • LeetCode 102 - 二叉树层次遍历详解
    本文详细解析了LeetCode第102题——二叉树的层次遍历问题,提供了C++语言的实现代码,并对算法的核心思想和具体步骤进行了深入讲解。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • 题目描述:Balala Power! 时间限制:4000/2000 MS (Java/Other) 内存限制:131072/131072 K (Java/Other)。题目背景及问题描述详见正文。 ... [详细]
  • 深入理解线程池及其基本实现
    本文探讨了线程池的概念、优势及其在Java中的应用。通过实例分析不同类型的线程池,并指导如何构建一个简易的线程池。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 洛谷 P4009 汽车加油行驶问题 解析
    探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
  • 本文探讨了在UIScrollView上嵌入Webview时遇到的一个常见问题:点击图片放大并返回后,Webview无法立即滑动。我们将分析问题原因,并提供有效的解决方案。 ... [详细]
  • JUC并发编程——线程的基本方法使用
    目录一、线程名称设置和获取二、线程的sleep()三、线程的interrupt四、join()五、yield()六、wait(),notify(),notifyAll( ... [详细]
  • 题目描述:计算从起点到终点的最小能量消耗。如果下一个单元格的风向与当前单元格相同,则消耗为0,否则为1。共有8个可能的方向。 ... [详细]
  • 前言:由于Android系统本身决定了其自身的单线程模型结构。在日常的开发过程中,我们又不能把所有的工作都交给主线程去处理(会造成UI卡顿现象)。因此,适当的创建子线程去处理一些耗 ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 本文提供了一个关于AC自动机(Aho-Corasick Algorithm)的详细解析与实现方法,特别针对P3796题目进行了深入探讨。文章不仅涵盖了AC自动机的基本概念,还重点讲解了如何通过构建失败指针(fail pointer)来提高字符串匹配效率。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 关于进程的复习:#管道#数据的共享Managerdictlist#进程池#cpu个数1#retmap(func,iterable)#异步自带close和join#所有 ... [详细]
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社区 版权所有