滑动窗口算法思路

滑动窗口算法思路

适用范围

  • 一般是字符串或者列表
  • 一般是要求最值(最大长度,最短长度等等)或者连续的子序列

算法思想

  • 在序列中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个窗口。
  • 先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的序列符合要求。
  • 此时,停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的序列不再符合要求。同时,每次增加 left前,都要更新一轮结果。
  • 重复第 2 和第 3 步,直到 right 到达序列的尽头。
    思路其实很简单:第 2 步相当于在寻找一个可行解,然后第 3 步在优化这个可行解,最终找到最优解。左右指针轮流前进,窗口大小增增减减,窗口不断向右滑动。

例如:力扣题目链接

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组

解题代码(Java):

class Solution {

    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                //left++体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}
int result = Integer.MAX_VALUE;
//如果这个地方大家想不到,其实也可以改成 result = nums.length+1

总结

遇到关于求最值的连续子序列可以使用滑动窗口
遇到去重的最值子串(子连续序列)等问题都可以使用滑动窗口。

posted @ 2022-03-06 22:22  贝贝子  阅读(91)  评论(0编辑  收藏  举报