【方法一 TreeMap】使用TreeMap<nums[i], cnt>,使用key来记录值,value记录这个值出现的次数,当窗口离开某个值的时候,先把它的计数-1,如果-到0就把这个值移除。
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>((a, b) -> { return b - a; });
int n = nums.length, m = n - k, i;
if(n == 0) return new int[0];
for(i = 0; i < k; i++){
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
int[] ans = new int[m + 1];
ans[0] = map.firstKey();
for(i = k; i < n; i++){
int left = nums[i - k];
int right = nums[i];
if(map.get(left) == 1) map.remove(left);
else map.put(left, map.get(left) - 1);
map.put(right, map.getOrDefault(right, 0) + 1);
ans[i - k + 1] = map.firstKey();
}
return ans;
}
}
【方法二 有序队列】使用有序队列来维护最大值以及后续的次大值,以样例为🌰
1,3,-1,-3,5, 3, 6, 7
一、首先将前三个加入队列
1:队列中只有1
3:从后往前检查队列,发现1比3小,让1出队列,原因是只要在这个窗口中还没滑到把3出走,那么最大值永远都是3,1对最大值已经没有任何帮助了,此时队列中只有3
-1:检查队列发现没有比-1小的,-1入队列,此时队列中有3,-1
这样第一个窗口的最大值就是队列的peek也就是3了。
二、滑动窗口的过程中,首先检查左侧丢掉的数是否为最大值,如果是最大值就把最大值出队列;然后检查右侧新加入的元素,入队在队列的什么地方。
第一次移动时:左侧1不在窗口内并且不是最大值,不用管;
右侧-3检查发现队列中没有<-3的,直接把-3入队列,此时队列中有3,-1,-3
更新完队列后最大值peek仍然是3.
第二次移动时:左侧3需要丢掉,同时因为它时最大值,此时要把队列的peek扔掉,
然后新加入了5,检查一遍队列,发现-3和-1都比5小,他们对后续的最大值已经不产生贡献了,所以直接出队列,并把5入队,此时队列中只剩5了,
同时最大值peek就是5了。
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0) return new int[0];
Deque<Integer> max = new LinkedList();
int n = nums.length, m = n - k, i;
int[] ans = new int[m + 1];
for(i = 0; i < k; i++){
while(!max.isEmpty() && max.peekLast() < nums[i]) max.pollLast();
max.offer(nums[i]);
}
ans[0] = max.peek();
for(i = k; i < n; i++){
if(nums[i - k] == max.peek()) max.poll();
while(!max.isEmpty() && max.peekLast() < nums[i]) max.pollLast();
max.offer(nums[i]);
ans[i - k + 1] = max.peek();
}
return ans;
}
}
套y总的板子
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int N = 100010;
int tt = -1, hh = 0, n = nums.length;
int[] q = new int[N];
int[] ans = new int[n - k + 1];
for (int i = 0, j = 0; i < n; i++) {
while (tt >= hh && i - q[hh] + 1 > k) hh++;
while (tt >= hh && nums[q[tt]] <= nums[i]) tt--;
q[++tt] = i;
if (i >= k - 1) ans[j++] = nums[q[hh]];
}
return ans;
}
}