算法打卡day11|栈与队列篇03|Leetcode 239. 滑动窗口最大值、347.前 K 个高频元素

小顶堆和大顶堆

小顶堆(Min Heap)和大顶堆(Max Heap)是两种特殊的完全二叉树,它们遵循特定的堆属性,即父节点的值总是小于或等于(小顶堆)或者大于或等于(大顶堆)其子节点的值。这种结构使得堆的根节点包含了最大值或者最小值,这使得堆在很多算法中非常有用,尤其是在优先级队列的实现上。

小顶堆(Min Heap)
在小顶堆中,每个非叶子节点的值都必须大于或等于其子节点的值。这意味着堆的根节点包含了所有节点中的最小值。小顶堆通常用于那些需要快速访问最小元素的场景比如实现优先队列也就是今天的力扣347题

大顶堆(Max Heap)
在大顶堆中,每个非叶子节点的值都必须小于或等于其子节点的值。因此,堆的根节点包含了所有节点中的最大值。大顶堆通常用于需要快速访问最大元素的场景

堆的操作
堆提供了几种基本操作:

  • insert(或add):向堆中添加一个新元素。
  • remove:移除堆中的最大元素(在大顶堆中)或最小元素(在小顶堆中)。
  • heapify:将一个数组转换成堆结构。
  • extractMax / extractMin:从堆中提取并移除最大元素(在大顶堆中)或最小元素(在小顶堆中)。

在Java中实现堆,Java标准库中的PriorityQueue就是基于堆实现的,默认情况下它使用小顶堆。可以指定一个Comparator来改变优先级队列的比较规则,从而可以实现大顶堆。

算法题

Leetcode  239. 滑动窗口最大值

题目链接:239. 滑动窗口最大值

大佬视频讲解:滑动窗口最大值视频讲解

个人思路

思路打结,不知道怎么实现

解法
单调队列

使用单调递减队列,将放进去窗口里的元素随着窗口的移动,队列也一进一出,每次移动之后,队列直接知道最大值是什么。

还有注意,队列没有必要维护窗口里的所有元素只需要维护有可能成为窗口里最大值的元素,同时保证队列里的元素数值是由大到小的。

设计单调队列的时候,pop,和push操作要保持如下规则:

  1. poll(val):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
  2. add(val):如果add的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到add元素的数值小于等于队列入口元素的数值为止

保持如上规则,每次窗口移动的时候,只要deque.peek()就可以返回当前窗口的最大值。

class MyQueue {Deque<Integer> deque = new LinkedList<>();//弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出;void poll(int val) {if (!deque.isEmpty() && val == deque.peek()) { //也要判断队列当前是否为空deque.poll();}}//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出,这样保证队列元素单调递减//比如此时队列元素4,3,1 ;5将要入队,比4,3,1都大,所以都弹出,此时队列:5void add(int val) {while (!deque.isEmpty() && val > deque.getLast()) {//push元素的数值小于等于队列入口元素的数值为止deque.removeLast();}deque.add(val);}//队列队顶元素始终为最大值int peek() {return deque.peek();}
}class Solution {public int[] maxSlidingWindow(int[] nums, int k) {if (nums.length == 1) {return nums;}int len = nums.length - k + 1;int[] res = new int[len];//存放结果元素的数组int num = 0;MyQueue myQueue = new MyQueue();//自定义队列//先将前k的元素放入队列for (int i = 0; i < k; i++) {myQueue.add(nums[i]);}res[num++] = myQueue.peek();for (int i = k; i < nums.length; i++) {myQueue.poll(nums[i - k]); //滑动窗口移除最前面的元素,移除是判断该元素是否放入队列myQueue.add(nums[i]);//滑动窗口加入最后面的元素res[num++] = myQueue.peek();//记录对应的最大值}return res;}
}

时间复杂度:O(n);(遍历数组)

空间复杂度:O(n);(辅助数组和队列)

Leetcode 347.前 K 个高频元素

题目链接:347.前 K 个高频元素

大佬视频讲解:前 K 个高频元素 视频讲解

个人思路

根据题意解答分为三步走,第一步要统计元素出现频率,第二步对频率排序,第三步找出前K个高频元素

解法
小顶堆

第一步统计元素出现的频率,这一类的问题可以使用map来进行统计。

第二步对频率进行排序,可以使用一种 容器适配器就是优先级队列,就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。

第三步找出前k个高频元素因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

如下图所示

class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数for(int num:nums){map.put(num,map.getOrDefault(num,0)+1);}//在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数//出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(小顶堆)PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]);for(Map.Entry<Integer,Integer> entry:map.entrySet()){//小顶堆只需要维持k个元素有序if(pq.size()<k){//小顶堆元素个数小于k个时直接加pq.add(new int[]{entry.getKey(),entry.getValue()});}else{if(entry.getValue()>pq.peek()[1]){//当前元素出现次数大于小顶堆的根结点//弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了pq.poll();pq.add(new int[]{entry.getKey(),entry.getValue()});}}}int[] ans = new int[k];//结果数组for(int i=k-1;i>=0;i--){//依次弹出小顶堆;先弹出的是堆的根,出现次数少,后面弹出的出现次数多ans[i] = pq.poll()[0];}return ans;}
}

时间复杂度:O(nlogk);(小顶堆构建)

空间复杂度:O(n);(优先队列,结果数组都不超过n)

以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网代码随想录算法官网代码随想录算法官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/728687.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring AOP相关注解及执行顺序

Aspect&#xff08;切面&#xff09;&#xff1a;用于标识一个类是切面的注解。通常与其他通知注解一起使用&#xff0c;定义切面类。 Pointcut&#xff08;切点&#xff09;&#xff1a; 注解来定义切点&#xff0c;它用于描述哪些连接点将会被通知所通知。 连接点&#xff…

Linux minfo命令教程:详解MS-DOS文件系统参数查看命令(附实例详解和注意事项)

Linux minfo命令介绍 minfo命令用于显示MS-DOS文件系统的各项参数&#xff0c;如磁区数、磁头数和柱面数等。它还可以打印一个mformat命令行&#xff0c;该命令行可以用于在其他媒体上创建类似的MS-DOS文件系统。 Linux minfo命令适用的Linux版本 minfo命令在大多数Linux发行…

算法D39 | 动态规划2 | 62.不同路径 63. 不同路径 II

今天开始逐渐有 dp的感觉了&#xff0c;题目不多&#xff0c;就两个 不同路径&#xff0c;可以好好研究一下 62.不同路径 本题大家掌握动态规划的方法就可以。 数论方法 有点非主流&#xff0c;很难想到。 代码随想录 视频讲解&#xff1a;动态规划中如何初始化很重要&#x…

Latex公式太长换行标号

Latex中公式太长换行&#xff0c;且编号&#xff0c;可以采用align&#xff0c;不编号行公式用\nonumber&#xff0c;示例如下&#xff1a; \begin{align}\nonumber %第1行公式不编号&abababababababa\\&cdm %第2行公式编号 \end{align}效果如下 原文件链接 公式不…

清除Mac OS上Xcode占用的空间

最近自己的Mac OS存储空间严重不足&#xff0c;想了一下&#xff0c;大概是从安装 Xcode 之后出现&#xff0c;在系统下通过 du 命令分析各目录大小&#xff0c;发现大概下面几个目录占用空间比较大&#xff0c;所以针对这几个名目录作了一下清理&#xff0c;释放了几十个G的空…

Leetcode 268 火星词典

题目描述&#xff1a; 现有一种使用英语字母的火星语言&#xff0c;这门语言的字母顺序与英语顺序不同。 给你一个字符串列表 words &#xff0c;作为这门语言的词典&#xff0c;words 中的字符串已经 按这门新语言的字母顺序进行了排序 。 请你根据该词典还原出此语言中已知…

<网络安全>《65 微课堂<第6课 网间文件安全交换系统>》

1 5中文件传输方式 1.1 通过U盘、硬盘、光盘等硬件介质传输 优势是成本低。 劣势是1、无法对这个行为过程进行监控管理。2、大文件较大、高频率交换时需要专人负责。3、由于这个过程并没有杀毒、内容检测等环节&#xff0c;因此具有较大的安全风险。 1.2 FTP、SFTP等跨网传输…

WordPress建站入门教程:如何上传安装WordPress主题?

我们成功搭建WordPress网站后&#xff0c;默认使用的是自带的最新主题&#xff0c;但是这个是国外主题&#xff0c;可能会引用一些国外的资源文件&#xff0c;所以为了让我们的WordPress网站访问速度更快&#xff0c;强烈建议大家使用国产优秀的WordPress主题。 今天boke112百…

【C语言】球球大作战

前言&#xff1a; 这款简易版的球球大作战是一款单人游戏&#xff0c;玩家需要控制一个小球在地图上移动&#xff0c;吞噬其他小球来增大自己的体积。本游戏使用C语言和easyx图形库编写&#xff0c;旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代码之前&#xf…

Flutter中TextFormField的属性及使用详解

在Flutter中&#xff0c;TextFormField是一个常用的组件&#xff0c;用于接收用户的文本输入。它具有丰富的属性&#xff0c;可以用于实现各种输入框的需求。在本篇博客中&#xff0c;我们将详细介绍TextFormField的属性以及如何使用它来创建文本输入框。 1. 属性介绍 下面是…

js 操作JSON对象查找、删除、增加和修改

对JSON的查找 格式1&#xff1a; datas.key 格式2&#xff1a; datas[key] 示例&#xff1a; var obj {name: "张三", age: 18, gender: "男"}; console.log(obj.name); // 格式1&#xff1a;输出 张三 console.log(obj[name]); // 格式2&#xff1a;输…

【MySQL 系列】MySQL 架构篇

在我们开始了解 MySQL 核心功能之前&#xff0c;首先我们需要站在一个全局的视角&#xff0c;来看 SQL 是如何运作执行的。通过这种方式&#xff0c;我们可以在头脑中构建出一幅 MySQL 各组件之间的协同工作方式&#xff0c;有助于我们加深对 MySQL 服务器的理解。 文章目录 1、…

【洛谷 P8707】[蓝桥杯 2020 省 AB1] 走方格 题解(动态规划)

[蓝桥杯 2020 省 AB1] 走方格 题目描述 在平面上有一些二维的点阵。 这些点的编号就像二维数组的编号一样&#xff0c;从上到下依次为第 1 1 1 至第 n n n 行&#xff0c;从左到右依次为第 1 1 1 至第 m m m 列&#xff0c;每一个点可以用行号和列号来表示。 现在有个人…

深入浅出运维可观测工具(四):如何使用eBPF绘制网络拓扑图

哈喽~又到了我们技术分享环节了。eBPF这个系列自分享以来收到了很多朋友的喜欢&#xff0c;真是让博主又惊又喜&#xff0c;感谢大家的支持。话不多说&#xff0c;今天我们将对如何使用eBPF绘制网络拓扑图做一篇分享&#xff0c;文章较长&#xff0c;干货较多&#xff0c;大家可…

R语言lavaan结构方程模型在复杂网络分析中的科研技术新趋势

此外&#xff0c;我们还将深入探讨R语言的基础知识、结构方程模型的基本原理、lavaan程序包的使用方法等内容。无论是潜变量分析、复合变量分析&#xff0c;还是非线性/非正态/缺失数据处理、分类变量分析、分组数据处理等复杂问题&#xff0c;我们都将一一为您解析。 希望通过…

微服务获取登录用户Id与单体服务下获取用户Id对比(黑马头条Day03)

前置声明 当前前后端分离开发项目中&#xff0c;后端某个请求向具体某个数据库中的多个表插入数据时&#xff0c;经常需要使用到当前登录用户的Id&#xff08;唯一标识&#xff09;。在当前用户线程下以实现变量共享&#xff0c;同时为了避免不同用户线程之间操作变量的影响&am…

【机器学习300问】28、什么是决策树?

〇、两个预测任务 &#xff08;1&#xff09;任务一&#xff1a;银行预测偿还能力 当前&#xff0c;某银行正致力于发掘潜在的放贷用户。他们掌握了每位用户的三个关键特征&#xff1a;房产状况、婚姻状况以及年收入。此外&#xff0c;银行还拥有过往这些用户的债务偿还能力的…

蓝桥杯简单题,公司名称

题目链接&#xff08;需要登录&#xff09; #include <iostream> #include <cstring> #include <algorithm> using namespace std; bool lanqiao(string str,int len){ sort(str.begin(),str.end());//对str按照ascii排序if(str.find("Laainoq")s…

题目 1825: 蓝桥杯-穿越雷区

题目描述: X星的坦克战车很奇怪&#xff0c;它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转&#xff0c;否则将报废。 某坦克需要从A区到B区去&#xff08;A&#xff0c;B区本身是安全区&#xff0c;没有正能量或负能量特征&#xff09;&#xff0c;怎样走才能路…

安卓Java面试题11-20

🔥 11、Android本身的API并未声明会抛出异常,则其在运行时有无可能抛出runtime异常,如何解决?🔥 会,比如nullpointerException。我遇到过,比如textview.setText()时,textview没有初始化。会导致程序无法正常运行出现forceclose。打开控制台查看logcat信息找出异常信…