「前端刷题」239.滑动窗口最大值(HARD)

100 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

题目(Sliding Window Maximum)

链接:leetcode-cn.com/problems/sl… 解决数:2606 通过率:50% 标签:队列 数组 滑动窗口 单调队列 堆(优先队列) 相关公司:amazon google facebook 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

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

示例 1:

输入: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 示例 2:

输入:nums = [1], k = 1 输出:[1]

提示:

1 <= nums.length <= 105 -104 <= nums[i] <= 104 1 <= k <= nums.length

思路

  1. 核心思路:维护一个单调队列,队头元素到队尾元素依次递减,然后最大值就是队列中的第一个元素
  2. 合法性判断:滑动窗口外的元素删掉
  3. 维护单调队列:如果新加进来的数大于等于队尾元素,则依次将队尾元素删除,始终维护队头元素是最大值
  4. 当满足滑动窗口区间范围时,将队头元素推入结果数组中。

代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
   const deque=[]; //存放单调队列的下标
   const  result=[]; 
   for(let i=0;i=k) deque.shift(); //在滑动窗口之外的直接从队头删掉
     while(nums[deque[deque.length-1]]<=nums[i]){
         deque.pop();  //如果新加进来的数比单调队列中原来的数都要大,则直接弹出队列中的其他数
     }
     deque.push(i);
     //数组下标从0开始,k=3时 ,下标为0,1,2的数组元素构成一个滑动窗口,所以条件为i>=k-1就可以将答案存入res中
     if(i>=k-1) {  
         result.push(nums[deque[0]]);
     }
   }
   return result;
};