当前位置: 首页 > article >正文

Leetcode面试经典150题-239.滑动窗口最大值

解法都在代码里,不懂就留言或者私信

官方定级hard难度,其实是medium,确实字节考过

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length == 1) {
            return new int[]{nums[0]};
        }
        /**我们要返回的是一个数组,这个窗口从遍历到第k个元素(下标k-1)的时候就形成了,所以最后返回结果的
        长度是n-(k-1)=n-k+1 */
        int[] ans = new int[nums.length - k + 1];
        /**看题意就知道肯定是滑动窗口了,题目标题就是滑动窗口的最大值,这还有啥说的
        我们先定义一个窗口,left表示窗口的左边界(包含),right表示窗口的右边界(不包含)
        窗口的有效范围是[left, right)的前闭后开区间,初始窗口是[0,0)
        表示窗口内没有值 */
        int left = 0;
        int right = 0;
        /**我们使用双向链表来表示这个窗口,我们这里只求最大值,所以定义一个链表即可
        这里链表里存的是下标 */
        LinkedList<Integer> maxWindow = new LinkedList<>(); 
        /**遍历数组统计,right每次都++,left只有窗口形成之后才++,所以如果有越界这回事,right肯定比left早越界
        所以无需判断left是否越界,这里写<=是为了收集最后一个窗口的最大值*/
        while(right <= nums.length) {
            /**下面就是要处理加入right之前窗口已经形成的情况了,如果加right之前窗口已经够k个了,那left位置应该淘汰 
            原来的窗口是[left, right),有效长度是right-left*/
            if(right - left == k) {
                /**既然窗口够了,那搜集一波最大值 */
                ans[left] = nums[maxWindow.peekFirst()];
                /**如果left位置是当前窗口最大值,那它出去了最大值就变了 */
                if(left == maxWindow.peekFirst()) {
                    /**把最大值去掉,以后的最大值还是pollFirst */
                    maxWindow.pollFirst();
                } 
                /**left向右移动,原来的left出窗口 */
                left ++;
            }
            /**如果right已经越界了,那就没有必要进行剩下的了 */
            if(right == nums.length) {
                break;
            }
            /**我们当前不管窗口形成还有没有形成,right位置都要入窗口(入链表或者说入队列) 
            因为链表中的元素是按照从first到last越来越小排列的,所以窗口不为空并且窗口中有小于等于(这里要注意的是等于也要淘汰,等于淘汰的理由是
            你在我前面肯定出窗口的时间早于我,即便都不出去,你可以作为最大值的情况我也可以,你早点出去我更是比你更适合当最大值)就淘汰
            */
            while(!maxWindow.isEmpty() && nums[maxWindow.peekLast()] <= nums[right]) {
                maxWindow.pollLast();
            }
            /**把小于等于last位置的都淘汰,last位置就可以入窗口了*/
            maxWindow.addLast(right);
            /**不管窗口够不够,right肯定要右移的 */
            right ++;
        }
        return ans;
    }
}


http://www.kler.cn/a/288057.html

相关文章:

  • RabbitMQ实战启程:从原理到部署的全方位探索(上)
  • K8S containerd拉取harbor镜像
  • Spring boot + Vue2小项目基本模板
  • 帽子矩阵--记录
  • 如何保证MySQL与Redis缓存的数据一致性?
  • 【LeetCode】【算法】5. 最长回文子串
  • Java集合记录
  • 苍穹初始-云与应用设计
  • 关于STC-ISP软件选项“下次下载用户程序时擦除用户EEPROM区”的质疑
  • 【CanMV K230】画图,画它个多啦A梦
  • 仿人机器人
  • 单片机-STM32 时钟(六)
  • 73.给定一个 m x n 的矩阵,实现一个算法如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法
  • Python多种列表操作方法
  • Django Admin在列表视图页面上显示计算字段
  • godot开发初体验
  • 黑马JavaWeb开发笔记13——Springboot入门(创建、运行测试项目)、Http协议(请求响应协议)、HTTP协议解析
  • 问:关于内部类,知道这些就够了~
  • C++初学(18)
  • Vue学习笔记 二
  • 【赵渝强老师】MongoDB的WiredTiger存储引擎
  • C#Math计算的几个常用方法
  • Pandas 1- 创建文件
  • 关键点检测(6)——yolov8-neck的搭建
  • 微信小程序背景图无法显示
  • 2409d,d语言非常简单利用sqlite3库