滑动窗口理解

本文深入解读滑动窗口算法,涉及三点关键要素:窗口内元素定义、起始位置移动策略和结束位置更新。通过LeetCode问题209举例,展示了如何从O(n^2)优化到O(n)复杂度。并提供了Java代码实现,适用于求解长度最小子数组和等于目标的问题。
摘要由CSDN通过智能技术生成

1、滑动窗口的理解

       滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。

2、滑动窗口需要确定的三点

主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

3、209. 长度最小的子数组 - 力扣(LeetCode) (leetcode-cn.com)

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,窗口的起始位置设置为数组的起始位置就可以了。

解题的关键在于 窗口的起始位置如何移动,如图所示:

leetcode_209

可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。

java实现:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // int start=0,end =  0;
        // int n = nums.length;
        // int min = Integer.MAX_VALUE;
        // while(start<n){
        //     while(end<n){
        //         int sum = 0;
        //         for(i = start;i<end+1;i++){
        //             sum+=nums[i];
        //         }
        //         if(sum<target)end++;
        //         else {
        //             min = Mah.min(min,end-start+1);
        //             start++;
        //         }
        //     }
        // }
        // return min;

        //暴力解决
        // int len = nums.length;
        // int sum = 0;
        // int tmpLen = Integer.MAX_VALUE;
        // for(int i=0; i<len; i++){
        //     sum = 0;
        //     for(int j=i; j<len; j++){
        //         sum += nums[j];
        //         if(sum>=target) tmpLen = Math.min(j-i+1,tmpLen);
                
        //     }
        // }
        // return tmpLen==Integer.MAX_VALUE ? 0:tmpLen;

        //滑动窗口
        int len = nums.length;
        if(len == 0)return 0;
        int ans = Integer.MAX_VALUE;
        int start =  0, end= 0;
        int sum = 0;
        while(end<len){
            sum += nums[end];
            while(sum >= target){
                ans = Math.min(ans, end - start + 1);
                sum -= nums[start];
                start++;
            }
            end++;
        }
        return ans == Integer.MAX_VALUE  ? 0:ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值