随着做题多了,最大的感受是,什么就是不要慌,即使一下子接口完了用不对,或者逻辑不对,导致的结果不对,都可以用:
极简案例数据 + 断点调试+解题思路!, 按照你的解题思路把结果给一步步找到,只要按照步骤来,观察每个步骤的对错就可以了!
解题思路:
第一种:窗口列表,遍历窗口最大值
1、我自己的解法,是用一个queue记录最大值,之后再通过遍历窗口queue获得最大值,welll done!~~我自己做出来的!
第二种:双向队列获取窗口最大值
官方的做法,则是高效许多,一个双向队列,搞定窗口移动过程中的最大值加入和淘汰,只是这个队列保存值比较特殊,是数组下标的index,为什么这样做?因为要用于淘汰掉,已经远离了当前窗口的旧数据。
具体做法:
1、定义一个双向队列,先初始化,填充 [0,size-1],值最大值的下标index!
2、之后,从size开始,遍历整个数组,逐渐找出下标最大的值,同样只要做好两件事就好了:
1)记录当前窗口,值最大的下标到队列
2)淘汰掉已经出了当前窗口的下标值
import java.util.*; public class Solution { /** * 这是我自己使用的方法,其实引入最大堆是浪费, * queue遍历的过程中就可以获得最大值了,所以无需最大堆浪费空间 * @param num int整型一维数组 * @param size int整型 * @return int整型ArrayList */ public ArrayList<Integer> maxInWindows2 (int[] num, int size) { ArrayList<Integer> res = new ArrayList<Integer>(); if (num == null || num.length == 0 || size == 0) { return res; } PriorityQueue<Integer> max = new PriorityQueue<Integer>((o1, o2)->o2.compareTo(o1)); LinkedList<Integer> queue = new LinkedList<Integer>(); for (int i = 0; i < size; i++) { max.offer(num[i]); queue.offer(num[i]); } res.add(max.peek()); int j = size; int n = num.length; while (j < n) { queue.offer(num[j]); queue.poll(); int maxInWin = addMaxInWindows(queue, max); res.add(maxInWin); j++; } return res; } private int addMaxInWindows(LinkedList<Integer> queue, PriorityQueue<Integer> max) { max.clear(); for (int i = 0; i < queue.size(); i++) { max.offer(queue.get(i)); } return max.peek(); } /** * 官方的方法,只是引入了双向队列arrayqueue就搞定了滑动窗口最大值的保存了 * @param num int整型一维数组 * @param size int整型 * @return int整型ArrayList */ public ArrayList<Integer> maxInWindows (int[] num, int size) { ArrayList<Integer> res = new ArrayList<Integer>(); if (num == null || num.length == 0 || size == 0 || num.length < size) { return res; } ArrayDeque<Integer> q = new ArrayDeque<Integer>(); for (int i = 0; i < size; i++) { // 淘汰掉小的数据 while (!q.isEmpty() && num[q.peekLast()] < num[i]) q.pollLast(); q.offer(i); } int n = num.length; for (int i = size; i < n; i++) { res.add(num[q.peekFirst()]); // 淘汰掉已经过了当前滑动窗口的数据 while (!q.isEmpty() && q.peekFirst() < (i - size + 1)) q.pollFirst(); // 跟上面一样,淘汰掉队列里小的数据 while (!q.isEmpty() && num[q.peekLast()] < num[i]) q.pollLast(); q.offer(i); } res.add(num[q.peekFirst()]); return res; } }