239. Sliding Window Maximum
题目链接:239. 滑动窗口最大值
思路链接:代码随想录栈与队列
思路
构造一个自己的队列。这个队列有三个特性:
- push时,从已有队列的last从last到first开始遍历,如果小于要push的值,则将last值remove;如果队列为空或者大于要push的值,则在队列末尾push
- pop时,如果队列的first与要pop的值相等,那么就将first remove。
- peek时return 队列first值
构造完以后,首先push数组中前k个值。然后从第k+1个值开始,首先pop掉滑动窗口前一个元素,然后在push。然后把peek返回的值加到result数组里。
心路历程
这道题有点复杂,看了视频文章代码后,自己实现也调试了好久,二刷时要巩固。
Code
import java.util.ArrayDeque;
class MyDeque {
Deque<Integer> deq = new ArrayDeque<>();
public void push(int num) {
// 注意这里要从小到大删,即从右往左删,否则会漏删
while (!deq.isEmpty() && deq.getLast() < num) {
// int deqPeek = deq.peek();
deq.removeLast();
}
deq.addLast(num);
}
public void pop(int num) {
// int deqPeek = deq.peek();
if (!deq.isEmpty() && deq.peek() == num) {
deq.removeFirst();
}
}
public int peek() {
return deq.getFirst();
}
public int size() {
return deq.size();
}
}
class Solution {
// 单调队列法 Runtime: O(n); 空间复杂度:O(k)
public int[] maxSlidingWindow(int[] nums, int k) {
// 初始化自定义deque以及result
MyDeque deq = new MyDeque();
int[] result = new int[nums.length - k + 1];
// 先将数组中前k个元素push进自定义deque
for (int i = 0; i < k; i++) {
deq.push(nums[i]);
result[0] = deq.peek();
}
// 滑动窗口移动,从第k个位置开始
for (int i = k; i < nums.length; i++) {
// result[i - k] = deq.peek();
deq.pop(nums[i - k]);
deq.push(nums[i]);
// deq.pop(nums[i - k]);
result[i - k + 1] = deq.peek();
}
return result;
}
}
347. Top K Frequent Elements
题目链接:347.前 K 个高频元素
思路链接:代码随想录栈与队列-前 K 个高频元素
思路
这道题思路比较简单,就是遍历数组,用map记录下每个key出现的次数(value),然后再用堆的数据结构来排序,大小顶堆都可以使用,从堆里poll掉k个元素就可以了。小顶堆比较快,大顶推无非就是稍微改一下Comparator和遍历的size就行。
心路历程
实现也花了一些时间,主要是Comparator有点忘了,去研究了一下,有时候得复习一下java的语法。
Code
class MyComparator implements Comparator<int[]> {
public int compare(int[] int1, int[] int2)
{
return int1[1] - int2[1];
}
}
class Solution {
// 小顶堆
// 时间复杂度:O(nlogk)
// 空间复杂度:O(n)
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
MyComparator cmp = new MyComparator();
for (int i : nums) {
map.put(i, map.getOrDefault(i, 0) + 1);
}
PriorityQueue<int[]> pq = new PriorityQueue<>(cmp);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (pq.size() < k) {
pq.add(new int[]{entry.getKey(), entry.getValue()});
} else {
pq.add(new int[]{entry.getKey(), entry.getValue()});
pq.poll();
}
}
int[] result = new int[k];
for (int i = k - 1; i >= 0; i--) {
result[i] = pq.poll()[0];
}
return result;
}
}
栈与队列总结
链接: 总结