JAVA二刷-Day13 | 239. 滑动窗口最大值, 347.前 K 个高频元素
今天的内容涉及到:
双向队列的定义和库:https://blog.youkuaiyun.com/top_code/article/details/8650729
小顶堆优先级队列的库:https://blog.youkuaiyun.com/BillieFan/article/details/107578057
滑动窗口最大值
LeetCode题目链接:https://leetcode.cn/problems/sliding-window-maximum/
解题思路
考虑到时间复杂度的问题,如果使用暴力解法的时间复杂度为 O ( n ∗ k ) O(n*k) O(n∗k),因此设计一个单调队列,使最大值一直保持在队首。同时,为了避免删去最大值时候,后面的顺序混乱,所以push时候要从尾部进行迭代,保证第二个值是第二大的。因此需要取得队列尾部元素的值,以及对队尾元素进行操作。因此需要双向队列来进行实现。
代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> llque = new ArrayDeque<Integer>();
ArrayList<Integer> result = new ArrayList<Integer>();
// int pre = 0;
for (int i = 0; i < k; i++) {
// if (i == 0) pre = nums[i];
while (!llque.isEmpty() && nums[i] > llque.peekLast()) {
llque.pollLast();
}
llque.offerLast(nums[i]);
}
result.add(llque.peekFirst());
for (int i = k; i < nums.length; i++) {
if (nums[i - k] == llque.peekFirst()) llque.poll();
while (!llque.isEmpty() && nums[i] > llque.peekLast()) {
llque.pollLast();
}
llque.offerLast(nums[i]);
result.add(llque.peekFirst());
}
return result.stream().mapToInt(x -> x).toArray();
}
}
前 K 个高频元素
LeetCode题目链接:https://leetcode.cn/problems/top-k-frequent-elements/
解题思路
主要在于掌握优先级队列,大小堆的概念,堆就是填满元素的完全二叉树。因为是要计算高频元素,因此在保存时不仅要保存元素的值,也应当保存元素出现的频次。因此使用map中的entry方法来进行遍历循环。并依靠数组的形式进行存储。
应当注意的是,在优先级队列中进行排序时,排序的顺序和仿函数中展示的顺序是相反的。同时,由于队列的FIFO原则,应该将小的放在队首用来pop。因此应该用小顶堆。
具体代码如下:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
PriorityQueue<int[]> pque = new PriorityQueue<>(new Comparator<int[]>() {
public int compare(int[] e1, int[] e2) {
//比较方法,此时为小顶堆,堆顶为最小元素。其中第二个为已经在堆中元素,第一个为新元素。
return e1[1] - e2[1];
}
});
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
if (pque.size() < k) {
pque.offer(new int[]{entry.getKey(), entry.getValue()});
}else if (pque.peek()[1] < entry.getValue()){
pque.poll();
pque.offer(new int[]{entry.getKey(), entry.getValue()});
}
}
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = pque.poll()[0];
}
return result;
}
}