Leetcode-239. 滑动窗口,“滑”的动作如何用代码体现?

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
分析
为了透彻分析这类问题,我会把大脑中 “智能”分析的过程 与 实际编码 一步步对应起来。这个分析的过程非常的重要,题目千千万,而分析过程所用的思想就那些,掌握了基本分析思想,就可以触类旁通。

  • 对于第一次接触这类题的小伙伴看完题目后可能立马就思考,这个 “滑动” 到底如何实现呢?发出这个问题的同时,想必在大脑中也会一直模拟题目给的样例,来反复滑动,试图找到一种合适的方式来实现这个 “滑动”。
  • 我们大脑思考的这个 “滑动” 的过程实际上是个非常 “智能” 的过程,想怎么滑动就怎么滑动。但是,对应具体实现程序来说就得一步步来,不能像我们大脑所想象的那样——可以跳动的滑动。
  • 首先第一步就是选择合适的数据结构,根据题目很明显就可以判断,要在一个线性数组中进行处理,与线性数组有关的容易想到 栈和 队列,那么这题用栈是不合适的,因为这不是单调栈的题目,那就选择队列,队列只是存储运算过程中的结果,并不是借助队列实现滑动。

滑动处理
其实在大脑中模拟这个滑动的过程中,我们其实就已经有了如何 处理 “滑动” 这两个字的过程了。

  • 第一步:既然是在数组中滑动,那么具体处理 “滑动” 的实现自然就是数组遍历了
  • 第二步:有了滑动的实现,再结合题目的限制条件——维护一个 k 长度的窗口,即维护一个长度为k的数组
  • 第三步:那么如何边滑动边维护呢?既然是遍历数组滑动,那肯定要通过 遍历到的当前元素下标与之前处理过的那些元素下标 来计算和对比,是否满足 长度 k 这个条件。

上面三步分析已经非常透彻的分析了这类题目如何处理。比如有些题目会用到双指针滑动窗口, 实现思路都是完全一致,再结合题目条件的限制,来判断每一步是left指针滑动还是right指针滑动,然后再一边滑动一边处理left 与 right 所维护的长度为 [right - left + 1] 的窗口中的值。
具体实现,参见代码。对于每个位置下标的处理,我也做了透彻的分析和说明,为什么 有的 地方 +1 或者-1。只有搞懂了每一步的意义,那么这种题做一遍就能深深的刻在脑海中。

public int[] maxSlidingWindow(int[] nums, int k) {
        int len = nums.length;
        if(len == 0 || k == 0) return new int[]{};
        int[] res = new int[len - k + 1];
        LinkedList<Integer> list = new LinkedList<>();
        int index = 0;
        for(int i = 0; i < len; i++) {
            //数组下标的每次移动就是滑动体现
            while(!list.isEmpty() && nums[i] >= nums[list.peekLast()]) {
                //滑的过程中要向题目要求靠拢
               //如果当前遍历到的元素nums[i] 大于队列中最后一个值,则我们需要的是较大值,所以弹出较小值
              //那如果不弹出 是不是就早就超过 k 的限制了
                list.pollLast();
            }
            list.addLast(i);
            //为什么这个条件就能判断队列中元素是否过期,因为数组小标总是比实际数组长度小
            //这里的k即可以理解为数组长度,i 为下标,如果 能用 [下标 - 数组长度] 这个表达式就说明 
            //数组肯定是越界了,即某个元素该淘汰了
            if(i - k == list.peekFirst()) {
                list.pollFirst();
            }
            //始终记住一点 k 可以理解为 我们维护的一个固定的数组长度
            //因为下标 始终小于 数组长度的, 因为要取 k 范围内的最小值,所k对应到下标中 要减1
            if(i >= k - 1) {
                res[index++] = nums[list.peekFirst()];
            }
        }
        return res;
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容