239. 滑动窗口最大值

题目描述

给你一个整数数组 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


做题思路

这个题目时Hard类型的,我第一遍看完题目后真实是一脸懵哈😄,甚至连需要使用什么方法都没头绪

然后我就默默的点开了官方的题解,看了一下官方的题解,没看太懂,然后翻了一下评论发现一位大神

写的评论非常清楚,看完它的解释,我叭叭的一顿狂写,过了!!!😄

我大概说一下简单的实现思路,只要理解了,实现起来不要太简单~

题目要求我们求在一个滑动窗口中的最大值,每次滑动窗口只向右移动一位

由上面这个信息可以知道,其实每次我们要求的最大值其实将上一次滑动窗口的最左边

的元素去除之后,剩下的元素加上这次我们新移动到元素的位置,再说的简单一点就是

每次窗口中的元素只有一个发生变化.

利用上面这个性质其实就可以想到利用优先队列,大堆的方式,去构造一个优先队列

我们可以按照降序的方式添加元素,但是考虑到 “最大的元素不在窗口的范围内” 所以我们还需要存入

元素对应的下标,每次都应该判断一下 q.peek() 的下标索引 是否<= i-k 如果小于等于说明当前

优先队列里面的元素虽然是最大的但是已经越界了.此时我们就需要将其出队列

判断完之后我们就可以往数组里面添加元素即可

  • 好了,以上我认为对于本题核心的部分已经总结出来了,如果你看到这里的话,先不要看我下面的代码实现,自己取力扣上看看能不能做出来

代码实现

class Solution {
  public int[] maxSlidingWindow(int[] nums, int k) {
    Queue<int[]> queue=new PriorityQueue<>(new Comparator<int[]>(){
      public int compare(int[] p1,int[] p2){
        return p1[0] != p2[0] ? p2[0]-p1[0] : p1[1]-p2[1];
      }
    });

    for(int i=0;i<k;i++){
      queue.offer(new int[]{nums[i],i});
    }
    int[] ant=new int[nums.length-k+1];
    ant[0]=queue.peek()[0];
    for(int i=k ; i<nums.length ;i++){
      queue.offer(new int[]{nums[i],i});
      while(queue.peek()[1]  <= i-k){
        queue.poll();
      }

      ant[i-k+1]=queue.peek()[0];
    }

    return ant;
  }
}

题目链接

239. 滑动窗口最大值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C_x_330

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值