1.代码随想录Day62.代码随想录Day7|哈希表part02 3.代码随想录Day8|字符串4.代码随想录Day9| 5.代码随想录Day10|栈与队列6.代码随想录Day11|栈和队列
7.代码随想录12|栈和队列
8.代码随想录Day14|二叉树9.代码随想录Day15|二叉树10.代码随想录Day15|二叉树III11.代码随想录算法训练营14期 Day112.代码随想录训练营day2| leetcode977, 209,5913.代码随想录day16| 二叉树(四)14.代码随想录Day17|二叉树(五)15.代码随想录Day19|二叉树(六)16.代码随想录|二叉树(最后一章)17.代码随想录|二叉树总结18.代码随想录Day23|回溯算法19.代码随想录Day24|回溯算法+JAVA大作战20.代码随想录|回溯算法(终回)21.代码随想录Day30|贪心122.代码随想录Day32|贪心II23.代码随想录|贪心III24.代码随想录|贪心(终章)25.代码随想录|动态规划26.代码随想录|动态规划-01背包问题27.代码随想录|完全背包28.代码随想录|打家劫舍问题29.代码随想录|各种买卖股票问题30.代码随想录|动态规划 - 子序列系列31.代码随想录|动态规划32.代码随想录|动态规划-编辑距离33.代码随想录|动态规划(终章)34.代码随想录|单调栈239. 滑动窗口最大值
这是使用单调队列的经典题目。
此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。
每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。
其实队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的
class MyQueue { Deque<Integer> deque = new LinkedList<>(); void poll(int val){ if(!deque.isEmpty() && val == deque.peek()){ deque.poll(); } } void add(int val){ while(!deque.isEmpty() && val > deque.getLast()){ 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 myQueeu = new MyQueue(); for(int i = 0; i < k; i++){ myQueeu.add(nums[i]); } res[num++] = myQueeu.peek(); for(int i = k; i< nums.length; i++){ myQueeu.poll(nums[i-k]); myQueeu.add(nums[i]); res[num++] = myQueeu.peek(); } return res; } }
347.前 K 个高频元素
什么是优先级队列呢?
其实就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。
缺省情况下priority_queue利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树)。
什么是堆呢?
堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
所以大家经常说的大顶堆(堆头是最大元素),小顶堆(堆头是最小元素),如果懒得自己实现的话,就直接用priority_queue(优先级队列)就可以了,底层实现都是一样的,从小到大排就是小顶堆,从大到小排就是大顶堆。
我们其实只需要维护k个有序的序列就可以了,所以使用优先级队列是最优的。
我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。
class Solution { public int[] topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for(int num: nums){ map.put(num, map.getOrDefault(num, 0)+1); } PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair1[1]-pair2[1]); for(Map.Entry<Integer,Integer> entry:map.entrySet()){ if(pq.size()<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; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~