对滑动窗口的一些理解

380 阅读1分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。

滑动窗口的理解

滑动窗口用来解决一些连续区间性质的问题,当区间发生变化时可以根据已知结果进行剪枝,这样可以减小计算量。

一般滑动窗口有连个指针,l,r,r用来扩展区间,而l用来压缩区间。

  1. 当窗口内的元素未达到题目条件时,右指针右移,探索未知的区间来满足条件
  2. 当窗口内的元素达到题目条件时,左指针右移,压缩区间,使窗口尽可能短得满足题目条件

滑动窗口常常会碰到区间越界的问题,这是因为使用while不容易把握区间,可以适当使用for循环来把握区间。

滑动窗口的常用模板

int slidingWindow(vector<int> nums) {
    int n = nums.size();
    int ans = 0;
    // 记录窗口内的元素及其个数,非必要
    map<int, int> um;
    // l:窗口左边界; r:窗口右边界
    int l = 0, r = 0;
    // r 指针负责探索新的区间,直到搜索到nums的某末尾
    while (r < n) {
        um[r]++;
        // 如果区间不满足条件,l指针右移,窗口收缩
        while(区间 [l, r] is Invalid) {
            um[l]--;
            l++;
        }
        // 此处处理结果, deal with(ans, 区间[l, r])
        res = max(ans, r - l + 1); // 或者res = min(ans, r - l + 1);
        // 右指针右移,继续搜索
        r++;
    }
    return ans;
}

滑动窗口例题

题目描述

leetcode 部分排序

题解

由于需要求的是一个区间,所以只需要找到最左和最右的需要参与重新排序的元素就可以了。

怎么找呢? 一个元素a[i]只需要满足他的左边存在一个数比他大或者右边存在一个元素比他小就可以了,那么我们就可以维护一个最大值,从左边开始遍历找到右端点,维护一个最小值,从右边开始遍历找到一个左端点即可。

如果是不需要重排序的话那么s,e将不会被赋值,基于此将s,e都赋值-1。

class Solution {
    public int[] subSort(int[] array) {
        int s=-1,e=-1;
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;
        for(int i=0; i<array.length; i++){
            if(array[i]>=max){
                max=array[i];
            }else{
                e=i;
            }
        }
        for (int i = array.length - 1; i >= 0; i--) {
            if(array[i]<=min){
                min=array[i];
            }else{
                s=i;
            }
        }
        return new int[]{s,e};
    }
}