day13 栈与队列 239. 滑动窗口最大值 347.前 K 个高频元素


 

补充:


JAVA 栈,为什么要使用Deque,而不推荐使用Stack,Deque中ArrayDeque与LinkedList的区别,Deque方法详解_java 栈为什么用deque-CSDN博客

239. 滑动窗口最大值

使用单调队列,这个队列,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。

队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列

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

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

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

自定义单调队列来实现出口元素为最大值,push来保证是单调递减的队列,如果插入的元素比队列中的元素大则使用while循环来依次移除,直到小于等于队列中的元素,保证了出口元素为最大值,而poll操作则保证了在例如3,-1,-3这种k=3的滑动窗口时往下滑动,下一个要删除的就是最大值3,来保证这种情况的正常执行,根本目的是为了移除递减队列中的最大值来保证滑动窗口的特点。

滑动窗口个数:int len = nums.length - k + 1;

滑动窗口实现先将k个元素放到队列当中然后再使用for循环从k开始,在循环内部弹出第i-k元素的值然后加入i的元素的值,模拟滑动窗口的移动过程,在poll中通过

if(!queue.isEmpty() && val == queue.peek()){
   queue.poll();
}

来判断是否需要弹出,因为push的时候可能已经将元素弹出,最后取队列出口元素放到结果数组当中。

单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。 不要以为本题中的单调队列实现就是固定的写法。

347.前 K 个高频元素

  • 时间复杂度: O(nlogk)
  • 空间复杂度: O(n)

这道题目主要涉及到如下三块内容:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

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

然后是对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列

定义一个大小为k的大顶堆,在每次移动更新大顶堆的时候,每次弹出都把最大的元素弹出去了,那么怎么保留下来前K个高频元素呢。而且使用大顶堆就要把所有元素都进行排序,那能不能只排序k个元素呢?所以我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

优先级队列

  • PriorityQueue底层使用了堆数据结构

大顶堆小顶堆  涉及到堆排序 详解看数据结构算法

map怎么使用foreach遍历

Java之五种遍历Map集合的方式 - 知乎 (zhihu.com)

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值