滑动窗口问题

滑动窗口问题

​ 牛客网 NC 87 滑动窗口的最大值

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

窗口大于数组长度的时候,返回空。

示例

输入:

[2,3,4,2,6,2,5,1],3

输出:

[4,4,6,6,6,5]
解题思路–双指针

​ 当窗口向右滑动时我们需要考虑两点,一是之前的最大值是否仍然有效(在窗口范围内),即之前的最大值下标是否大于等于窗口的左边界。当之前的最大值下标在窗口范围内时,此时只需判断滑动窗口右侧新增加的数是否大于最大值,做相应更新最大值和最大值下标操作。而最大值下标已经失效时,此时最大值失效,我们就需要重新计算从窗口左侧到右侧的最大值。

​ 我们把滑动窗口的左右边界分别设置为 i 和 j ,初始化时 i = 0,j = 滑动窗口大小 - 1,最大值下标maxInd = -1为了让第一次循环时计算出 i 到 j 区间的最大值。 而上面提到的最大值失效,即最大值下标maxInd = i - 1 < i,此时我们需要重新计算 i 到 j 区间内的最大值。而最大值有效值,只需要判断新加入滑动窗口的数 num[j] 是否大于之前的最大值。

import java.util.*;

public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        ArrayList<Integer> list = new ArrayList();
        int n = num.length;
        if(n < size || size == 0 || n == 0)
            return list;
        int i = 0, j = size - 1;
        int maxVal = 0, maxInd = -1;
        while(j < n) {
            //最大值下标小于i,需要计算从i到j的最大值
            if(maxInd < i) {
                int k = i + 1;
                maxVal = num[i];
                maxInd = i;
                while(k <= j) {
                    if(maxVal < num[k]) {
                        maxInd = k;
                        maxVal = num[k];
                    }
                    k++;
                }
            //最大值下标maxInd大于等于i(最大值仍然有效)
            //只需要判断新划入到窗口内的num[j]是否大于最大值maxVal
            } else {
                if(maxVal < num[j]) {
                    maxVal = num[j];
                    maxInd = j;
                }
            }
            ++i; ++j;
            list.add(maxVal);
        }
        return list;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值