Leetcode239.滑动窗口最大值——小总结

国庆前参加了人生第一场实习面试,还是发现了很多不足,面试的一道编程题是leetcode239滑动窗口最大值,主要是看了这条视频小美算法 剑指Offer59题 滑动窗口的最大值 java版本 一句口诀搞定单调双端队列的构建_哔哩哔哩_bilibili才最终看懂双端队列的思路。

题目描述

题目链接力扣

解题思路

1.暴力法求解

        面试时第一个想到的就是暴力法,双循环,外层n-k+1,内层为k。此数组有n个元素,滑动窗口大小为k,所以窗口总共需要走n-k+1次,每次在窗口中的k个元素还需要找出最大值,因此时间复杂度为O(n*k)。但是面试官要求使用尽可能小的时间复杂度,因此我没有使用暴力法。

2.双端队列

双端队列法使用的数据结构是Deque,Deque存储数组下标,主要思路是保证每次循环deque的对头是此次滑动窗口最大值,主要步骤如下:

首先声明一个数组res作为结果返回,数组大小为n-k+1

1)每次操作前先去除队列头部:滑动窗口右移要先删除一个元素

2)将队列中比当前值小的值的下标都去除:循环的条件是 !deque.isEmpty() && num[i]>=nums[deque.getLast]

3)将当前值的下标加入deque

4)将队头下标对应的值加入res,即 res[n-k+1] = nums[deque.getFirst()]

代码如下:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int length = nums.length;
        if(length==1) return nums;

        int[] res = new int[length-k+1];

        //Deque双端队列存储的是数组的下标,不是数组的值
        Deque<Integer> dq = new LinkedList<>();

        for(int i=0;i<length;i++){
            //Step1:头出队
            if(!dq.isEmpty() && dq.getFirst()<i-k+1){
                dq.removeFirst();
            }

            //Step2:去除尾部比当前值小的值
            while(!dq.isEmpty() && nums[i]>=nums[dq.getLast()]){
                dq.removeLast();
            }

            //Step3:当前值的下标加入尾部
            dq.addLast(i);

            //Step4:头部的值是当前滑动窗口的最大值,加入res
            if(i-k+1>=0)
                res[i-k+1] = nums[dq.getFirst()];

        }
        return res;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值