滑动窗口最大值

该文章介绍了如何使用双端队列(Deque)解决滑动窗口最大值的问题。给定一个整数数组nums和窗口大小k,算法通过遍历数组并维护一个单调递减的Deque,来实时更新每个窗口的最大值。当窗口移动时,队列会删除超出窗口范围和小于当前元素的值,确保队首始终为当前窗口的最大值。
摘要由CSDN通过智能技术生成

题目描述:

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

解题思路:

       循环遍历数组中的元素,用一个双端队列Deque存储每次遍历的元素的下标,根据题目给出的滑动窗口的大小k以及用于循环遍历的 i 可以得到滑动窗口的起始位置:i - k + 1,由此也可以得到滑窗的末端位置为 i,在将元素下标加到Deque中前需要判断队头元素是否在滑窗之外(deque.peek() < i - k + 1),如果是的话则将队头元素出队,然后还需要判断目前数组中的元素是否大于队尾元素(nums[ i ] > nums[deque.peekLast()]),是的话则将队尾元素移除以保证队列中的元素都是单调递减的, 在滑窗值满足时可以将队列中元素所对应的值加入到结果数组中,之后就重复以上步骤直至遍历完毕。

代码如下:

     

public class SlidingWindowMax {
    public static int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || nums.length == 0 || k <= 0 || k > nums.length) {
            return new int[0];
        }

        int[] result = new int[nums.length - k + 1];
        int index = 0;

        // 创建一个双端队列来存储数组元素的下标

        Deque<Integer> deque = new ArrayDeque<>();  

        for (int i = 0; i < nums.length; i++) {

            // 移除窗口外的元素,即队列头部的元素不在当前窗口的范围内

            while (!deque.isEmpty() && deque.peek() < i - k + 1) {
                deque.poll();
            }

            // 移除队列中比当前元素小的元素,因为它们不可能成为窗口中的最大值

            while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
                deque.pollLast();
            }

            // 添加当前元素下标到队列中

            deque.offer(i);

            // 当窗口完全覆盖时,记录窗口中的最大值,即队列头部的元素

            if (i >= k - 1) {
                result[index++] = nums[deque.peek()];
            }
        }

        return result;  // 返回结果数组
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值