zoukankan      html  css  js  c++  java
  • 滑动窗口最大值-双向队列

    package Leetcode;
    
    import java.util.LinkedList;
    /**
     * 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
    返回滑动窗口中的最大值。(时间复杂度限制)
     */
    public class test239 {
        public static void main(String[] args) {
            int []nums={1,3,-1,-3,5,3,6,7};
            int k=3;
            int []result=maxSlidingWindow(nums, k);  
            int x=0;
        }
        //双向链表存储最大值index位置
        ///遍历数组,将 数 存放在双向队列中,并用 L,R 来标记窗口的左边界和右边界。队列中保存的并不是真的 数,而是该数值对应的数组下标位置,
        // 并且数组中的数要从大到小排序。如果当前遍历的数比队尾的值大,则需要弹出队尾值,直到队列重新满足从大到小的要求。刚开始遍历时,
        // L 和 R 都为 0,有一个形成窗口的过程,此过程没有最大值,L 不动,R 向右移。当窗口大小形成时,L 和 R 一起向右移,每次移动时,
        // 判断队首的值的数组下标是否在 [L,R] 中,如果不在则需要弹出队首的值,当前窗口的最大值即为队首的数。
        // R=i,L=k-R。由于队列中的值是从大到小排序的,所以每次窗口变动时,只需要判断队首的值是否还在窗口中就行了。
        // 解释一下为什么队列中要存放数组下标的值而不是直接存储数值,因为要判断队首的值是否在窗口范围内,由数组下标取值很方便,而由值取数组下标不是很方便。
    
        public static int[] maxSlidingWindow(int[] nums, int k) {
            if(nums==null||nums.length<2){
                return nums;
            }
            LinkedList<Integer> queue=new LinkedList<>();
            int []result=new int[nums.length-k+1];
            for(int i=0;i<nums.length;i++){
                while(!queue.isEmpty()&&nums[queue.peekLast()]<=nums[i]){
                    queue.pollLast();
                }
                queue.add(i);
                if(queue.peek()<=i-k){
                    queue.poll();
                }
                if(i+1>=k){
                    result[i+1-k]=nums[queue.peek()];
                }
            }
            return result;
        }
    
        
    }
  • 相关阅读:
    ZZNU 1995: cots' times
    网站后缀名都有哪些
    webstorm运行到服务器(Apache)
    window系统下node.js环境配置
    window系统安装node.js
    网站创建自定义百度地图
    响应式一级到三级导航
    H5插入视频兼容各大浏览器
    phpStudy环境安装
    jquery on和bind
  • 原文地址:https://www.cnblogs.com/jieyi/p/14223751.html
Copyright © 2011-2022 走看看