LeetCode每日一题-2:滑动窗口的最大值

简介: LeetCode每日一题-2:滑动窗口的最大值

题目描述:


给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:


输入: 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

思路分析:


考虑到这道题的数组要求可以头部进去、删除,尾部进去,删除,所以使用双端队列Deque。使用双端队列的单调双端队列LinkedList实现。

所谓的单调,就是我们人为规定从队列的头部到尾部,所存储的元素是依次递减(或依次递增)的。

也就是说,我们维护一个单调的双向队列,窗口在每次滑动的时候,我就从队列头部取当前窗口中的最大值,每次窗口新进来一个元素的时候,我就将它与队列中的元素进行大小比较:

如果刚刚进来的元素比队列的尾部元素大,那么先将队列尾部的元素弹出,然后把刚刚进来的元素添到队列的尾部;

如果刚刚进来的元素比队列的尾部元素小,那么把刚刚进来的元素直接添到队列的尾部即可。

因此,通过这种既能从头部进出,又能从尾部进出的结构,来维持窗口的最大值的。

Python代码


# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # write code here
        # 存放可能是最大值的下标
        maxqueue = []
        # 存放窗口中最大值
        maxlist = []
        n = len(num)
        # 参数检验
        if n == 0 or size == 0 or size > n:
            return maxlist
        for i in range(n):
            # 判断队首下标对应的元素是否已经滑出窗口
            if len(maxqueue) > 0 and i - size >= maxqueue[0]:
                maxqueue.pop(0)
            while len(maxqueue) > 0 and num[i] > num[maxqueue[-1]]:
                maxqueue.pop()
            maxqueue.append(i)
            if i >= size - 1:
                maxlist.append(num[maxqueue[0]])
        return maxlist

java代码:


class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> deque=new LinkedList<>();
        int len=nums.length;
        if(len==0 ||k==0 ){
            return new int[0] ;
        }
        int[] res=new int[len-k+1];
        for(int i=0;i<k;i++){
            while(!deque.isEmpty() && nums[i]>deque.peekLast()){
                deque.removeLast(); //比队列元素大就弹出队尾数据
            }
            deque.addLast(nums[i]);//不走循环直接加到队列末尾
        }
        res[0]=deque.peekFirst();
        for(int i=k;i<len;i++){
            // 如果滑动窗口已经略过了队列中头部的元素,则将头部元素弹出
            if(deque.peekFirst() == nums[i - k]){
                deque.removeFirst();//
            }
            while(!deque.isEmpty() && deque.peekLast() < nums[i]){
                deque.removeLast();
            }
            deque.addLast(nums[i]);
            res[i - k + 1] = deque.peekFirst();
        }
        return res;
    }
}

交流


对于代码或是题目有什么问题都可以通过留言或是公众号子菜单联系我,一起交流学习!

相关文章
|
1月前
|
存储 Python
【Leetcode刷题Python】239. 滑动窗口最大值
文章介绍了两种解决LeetCode上"滑动窗口最大值"问题的方法:使用大堆树和双向递减队列,提供了详细的解析和Python代码实现。
14 0
|
3月前
|
算法 搜索推荐
力扣每日一题 6/15 滑动窗口
力扣每日一题 6/15 滑动窗口
20 1
|
2月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
3月前
|
算法
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
|
3月前
|
算法 容器
【LeetCode刷题】滑动窗口解决问题:水果成篮、找到字符串中所有字母异位词
【LeetCode刷题】滑动窗口解决问题:水果成篮、找到字符串中所有字母异位词
|
3月前
|
算法 索引
力扣随机一题 位运算/滑动窗口/数组
力扣随机一题 位运算/滑动窗口/数组
29 0
|
3月前
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
|
3月前
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
|
3月前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
3月前
|
存储 算法 数据可视化
深入解析力扣159题:至多包含两个不同字符的最长子串(滑动窗口法详细图解)
深入解析力扣159题:至多包含两个不同字符的最长子串(滑动窗口法详细图解)