0双端队列困难 LeetCode239. 滑动窗口最大值

239. 滑动窗口最大值

描述

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

分析

暴力解法很容易想到,难的是容易遍历一遍就能解决问题,使用双向队列就可以做到。
让这个双线队列保持单调递减这样就能很快找到某一段区间最大的数值。
维持双向队列的单调性需要以下两个步骤:

  1. 末端加入元素。只要不为空且队列末尾元素小于当前元素,则一直弹出队列末尾元素。
  2. 剔除超过区间的头部元素。若头部元素的下标小于i-k+1,说明要被踢出去了,这样才能保持滑动窗口的长度一直是k

注意:

  • 队列中保存的并不是真的数,而是该数值对应的数组下标位置,这样方便剔除头部超出区间的数值。
  • 当i大于等于k - 1时才收集最大值。
class Solution {
    
    
    public int[] maxSlidingWindow(int[] nums, int k) {
    
    
        LinkedList<Integer> deque = new LinkedList<>();
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < nums.length; i++){
    
    
            while(deque.size() != 0 && nums[deque.peekLast()] <= nums[i]){
    
    
                deque.pollLast();
            }
            deque.offerLast(i);
            if(deque.peekFirst() < i-k+1){
    
    
                deque.pollFirst();
            }
            if(i >= k - 1){
    
    
                list.add(nums[deque.peekFirst()]);
            }
        }
        int[] res = new int[list.size()];
        for(int i = 0; i < res.length; i++){
    
    
            res[i] = list.get(i);
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43260719/article/details/120790967