题解 | 滑动窗口的最大值(腾讯二面)
滑动窗口的最大值
https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int[] num, int size) {
ArrayList<Integer> res = new ArrayList<>();
if (num == null || size <= 0 || size > num.length)
return res; // 处理边界情况
Deque<Integer> deque = new ArrayDeque<>(); // 存储索引的双端队列
for (int i = 0; i < num.length; i++) {
// 1. 移除超出窗口范围的队头元素,用i-size+1 到 i 来维持双端队列的范围,
while (!deque.isEmpty() && deque.peekFirst() < i - size + 1) {
deque.pollFirst();
}
// 2. 维护队列单调递减:从队尾移除小于当前值的元素
while (!deque.isEmpty() && num[deque.peekLast()] < num[i]) {
deque.pollLast();
}
// 3. 当前索引入队
deque.offerLast(i);
// 4. 当窗口形成后,记录当前窗口最大值
if (i >= size - 1) {
res.add(num[deque.peekFirst()]); // 队头即最大值
}
}
return res;
}
}
当时腾讯csig二面考过,我写的双指针法+单调队列, 面试官一直追问还有什么方法,当时没答出来。 今天重新做这道题,用一个单调递减的双端队列来维持滑动窗口,最后返回的头元素就是滑动窗口的最大值。 首先分两部 1. 就是移除窗口内的左侧元素(过期元素因为要往右移动遍历) 用 (i-size +1, i) 这个区间来维护,2.移动比较 最小的元素,从队尾移除所有小于当前元素的索引(因为它们不可能是后续窗口的最大值), 之后,当前元素入队, 再将 窗口内的 头元素(最大值)加入 new的 arraylist中,返回res
#手撕代码##笔试#