我新建的个人博客,欢迎访问:hmilzy.github.io
239. 滑动窗口最大值
题目链接: 滑动窗口最大值
创建一个单调队列,队列里放数组的下标位置
遍历数组,若队列首的值不在窗口内,则从队首一直poll元素,直到满足
若队列尾的元素小于当前遍历到的数组元素值,则不断将队尾元素移除
然后将数组元素位置放入队列
判断遍历到的地方是否大于等于k-1,来给结果数组赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int[] maxSlidingWindow(int[] nums, int k) { Deque<Integer> deque = new LinkedList<Integer>(); int n = nums.length; int[] result = new int[n - k + 1]; for(int i = 0; i < n; i++){
while(!deque.isEmpty() && deque.peek() < i - k + 1) { deque.poll(); } while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { deque.pollLast(); }
deque.offer(i); if(i >= k - 1){ result[i - k + 1] = nums[deque.peek()]; } } return result; } }
|
347. 前 K 个高频元素
题目链接: 前 K 个高频元素
此时要思考一下,是使用小顶堆呢,还是大顶堆?
有的同学一想,题目要求前 K 个高频元素,那么果断用大顶堆啊。
那么问题来了,定义一个大小为k的大顶堆,在每次移动更新大顶堆的时候,每次弹出都把最大的元素弹出去了,那么怎么保留下来前K个高频元素呢。
而且使用大顶堆就要把所有元素都进行排序,那能不能只排序k个元素呢?
所以我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。
本题的思路是采用小顶堆(注意分清大小顶堆的使用)
优先队列作为小顶堆,注意优先队列顺序的初始化
从hashmap保存每个元素出现的次数
遍历hashmap,将元素放进去,挤出来,最后遍历完留下的就是前K个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int[] topKFrequent(int[] nums, int k) { PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]); int[] res = new int[k]; Map<Integer, Integer> map = new HashMap<>(); for(int num : nums) map.put(num, map.getOrDefault(num, 0) + 1); for(var x : map.entrySet()) { int[] tmp = new int[2]; tmp[0] = x.getKey(); tmp[1] = x.getValue(); pq.offer(tmp); if(pq.size() > k) { pq.poll(); } } for(int i = 0; i < k; i ++) { res[i] = pq.poll()[0]; } return res; } }
|