算法训练营(day13)
239.滑动窗口最大值
题目链接:https://leetcode.cn/problems/sliding-window-maximum/description/
给你一个整数数组 nums
,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。
解题思路
解题过程:
- 本题使用 双端队列 进行解答
- 主要思路是 定义队列存放数组下标,再定义新数组存放窗口内最大值的下标定义的值
- 要满足在滑动窗口内找最大值,需要在
[i - k + 1, i]
中选到最大值,不符合就要弹出
- 要考虑如何使队列存放最大值的下标 – 始终保持队列首部为最大值的下标 ,不符合就弹出
- 新数组要在
i - k + 1 >= 0
后,说明滑动窗口内已经填充足够的值,再开始存储最大值
详细代码
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
| class Solution { public int[] maxSlidingWindow(int[] nums, int k) { if(nums == null || k < 1 || nums.length < k){ return null; } Deque<Integer> deque = new ArrayDeque<>(); int[] res = new int[nums.length - k + 1]; int index = 0;
for(int i = 0; i < nums.length; i++){ while(!deque.isEmpty() && deque.peekFirst() < i - k + 1){ deque.pollFirst(); } while(!deque.isEmpty() && nums[deque.peekLast()] <= nums[i]){ deque.pollLast(); } deque.offer(i);
if(i >= k - 1){ res[index++] = nums[deque.peekFirst()]; } } return res; } }
|
347.前K个高频元素
题目链接:https://leetcode.cn/problems/top-k-frequent-elements/description/
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
解题思路
解题过程:
- 本题使用 优先级队列 求解
- 首先是使用
map
统计 每个整数的 种类key 以及 出现次数value
- 在 优先级队列 中存储
map
这个 二元组
- 根据 优先级队列 的排序规则,依次弹出
k
个优先级队列的元素,即得到结果
详细代码
解法一:使用大根堆求解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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[]> queue = new PriorityQueue<>((pair1, pair2) -> pair2[1] - pair1[1]);
for(Map.Entry<Integer, Integer> entry : map.entrySet()){ queue.add(new int[]{entry.getKey(), entry.getValue()}); } int[] ans = new int[k]; for(int i = 0; i < k; i++){ ans[i] = queue.poll()[0]; } return ans; } }
|
解法二:使用小根堆求解
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 28
| 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[]> queue = new PriorityQueue<>((pair1, pair2) -> pair1[1] - pair2[1]);
for(Map.Entry<Integer, Integer> entry : map.entrySet()){ if(queue.size() < k){ queue.add(new int[]{entry.getKey(), entry.getValue()}); }else{ if(entry.getValue() > queue.peek()[1]){ queue.poll(); queue.add(new int[]{entry.getKey(), entry.getValue()}); } } } int[] ans = new int[k]; for(int i = 0; i < k; i++){ ans[i] = queue.poll()[0]; } return ans; } }
|