• LeetCoded第239题题解--滑动窗口最大值


    滑动窗口最大值

    给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

    返回滑动窗口中的最大值。

    进阶:

    你能在线性时间复杂度内解决此题吗?

    示例:

    输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
    输出: [3,3,5,5,6,7]
    解释:

    滑动窗口的位置 最大值


    [1 3 -1] -3 5 3 6 7 3
    1 [3 -1 -3] 5 3 6 7 3
    1 3 [-1 -3 5] 3 6 7 5
    1 3 -1 [-3 5 3] 6 7 5
    1 3 -1 -3 [5 3 6] 7 6
    1 3 -1 -3 5 [3 6 7] 7

    提示:

    1 <= nums.length <= 10^5
    -10^4 <= nums[i] <= 10^4
    1 <= k <= nums.length

    解题思路

    一: 移动窗口,扫描,获取最大值,假设数组里有n个元素,算法的复杂度是O(n)。
    二: 利用一个双端队列来保存当前窗口中最大那个数在数组里的下标,双端队列新的头就是当前窗口最大的那个数。通过该下标,可以很快知道新窗口是否仍包含原来那个最大的数。如果不包含,我们就把旧数据同双端队列头删除。

    java解法

     public int[] maxSlidingWindow(int[] nums, int k) {
            //处理边界值, 定义变量消除魔法值
            int min = 2;
            if (nums==null||nums.length< min){
                return nums;
            }
            //创建双向队列
            Deque<Integer> deque = new LinkedList<>();
            //创建结果数组
            int[] result = new int[nums.length-k+1];
            for (int i = 0; i < nums.length; i++) {
                //判断入值是否小于队尾值,保证队列大小顺序,确保最大值位于对头
                while (deque.size()!=0&&nums[deque.peekLast()]<nums[i]){
                    deque.removeLast();
                }
                //将数据加入队列
                deque.addLast(i);
                //移除超出窗口的数据
                if (deque.peekFirst()<=i-k){
                    deque.removeFirst();
                }
                //从第k-1个值开始存入最大值
                if (i+1>=k){
                    result[i+1-k] = nums[deque.peekFirst()];
                }
            }
            return result;
        }
    
  • 相关阅读:
    Eclipse MarketPlace 打不开,对话框闪退
    docker 创建容器的时候的坑
    win7 设置docker加速器
    postgres常用命令
    docker加速器配置
    docker 安装 postgresql
    Spring Cloud-服务的注册与发现之服务注册中心(Eureka Server)
    redis incr自增指定的无限期 key 删除问题
    redis读取自增时候指定的key问题
    docker 安装 redis
  • 原文地址:https://www.cnblogs.com/zhangguangxiang/p/14232491.html
Copyright © 2020-2023  润新知