作业题
239. 滑动窗口最大值
class Solution { class MyQueue { Deque<Integer> deque = new LinkedList<>(); //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出 //同时判断队列当前是否为空 void poll(int val) { if (!deque.isEmpty() && val == deque.peek()) { deque.poll(); } } //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出 //保证队列元素单调递减 //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2 void add(int val) { while (!deque.isEmpty() && val > deque.getLast()) { deque.removeLast(); } deque.add(val); } //队列队顶元素始终为最大值 int peek() { return deque.peek(); } } 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; } }
347. 前 K 个高频元素
package jjn.carl.stack_queue; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.PriorityQueue; /** * @author Jiang Jining * @since 2023-07-11 0:12 */ public 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) -> pair2[1] - pair1[1]); for (Map.Entry<Integer, Integer> entry : map.entrySet()) {//大顶堆需要对所有元素进行排序 pq.add(new int[]{entry.getKey(), entry.getValue()}); } int[] ans = new int[k]; for (int i = 0; i < k; i++) {//依次从队头弹出k个,就是出现频率前k高的元素 ans[i] = Objects.requireNonNull(pq.poll())[0]; } return ans; } }
总结
栈经典题型
括号匹配
字符串去重
逆波兰表达式问题
队列经典题型
滑动窗口最大值问题
求前 K 个高频元素
什么是优先级队列呢?
其实就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。