滑动窗口算法思想图解说明

滑动窗口算法

滑窗思想在解决一些联系子数组问题上被广泛应用,遇到对一些给定长度的子数组序列进行操作  或者求解子串问题,首先想到滑窗技巧

  • 滑窗思想模板

最为经典的滑窗算法有其固定的解题模板

下面就通过一段伪代码的形式对滑窗思想进行阐述

int left = 0, right = 0;

while (right < s.size()) {
    // 增大窗口
    window.add(s[right]);
    right++;

    while (window needs shrink) {
        // 缩小窗口
        window.remove(s[left]);
        left++;
    }
}
  • 滑窗思想应用

接下来通过几道算法题目对滑窗思想进行应用

  • 对定长子数组操作

  • (1)子数组的最大平均值

滑动窗口算法思想图解说明_第1张图片

double findMaxAverage(int* nums, int numsSize, int k)
{     
    int arrsum=0;     //先前 k 个元素作为一个窗口     
    for(int i=0;imaxsum?arrsum:maxsum;     
    }     
    return (double)maxsum/k; 
} 
 

根据定长滑窗,计算前k个数值所组成滑窗的和大小,k个为一组向后滑动即可,每次减去窗口前一个元素,加上窗口后一个元素实现窗 口后移查找.

举例说明:考虑数组arr [] = { 5,2,-1,0,3 },k = 3

滑动窗口算法思想图解说明_第2张图片

滑动窗口算法思想图解说明_第3张图片

滑动窗口算法思想图解说明_第4张图片

基本上依靠模板进行滑窗移动,左右边界作为滑窗边界,

左边界左移,以及右边界右移  导致滑窗尺寸变大

左边界右移,以及右边界左移  导致滑窗尺寸变小

  • (2)滑动窗口的最大值

滑动窗口算法思想图解说明_第5张图片

class Solution {
public:
    vector maxSlidingWindow(vector& nums, int k) {
        vectorres;
        if(nums.size()==0)
        {
            return res;
        }
        int n=nums.size()-k+1;//窗口数
        int t=-1;//当前窗口最大值下标
        int max;//当前窗口最大值

        for(int i=0;imax)
                    {
                        t=j;
                        max=nums[j];
                    }
                }
            }
            else//上个滑窗最大值在当前窗口里
            {
                if(nums[i+k-1] >= max)//注意,此时滑动窗口移动,只新增一个数 只需要与新增的数比较即可
                {
                    t = i+k-1;
                    max = nums[i+k-1];
                }
            }
            res.push_back(max);
        }
        return res;
    }
};

对于定长滑窗,可以根据整个数组长度以及滑窗长度,确定滑窗个数nums.size()-k+1

滑动窗口算法思想图解说明_第6张图片

  • 最大子序和

滑动窗口算法思想图解说明_第7张图片

class Solution {
public:
    int maxSubArray(vector& nums) {
        if(nums.size()==0)
        {
            return 0;
        }
        int left=0;//滑窗  左边界索引
        int right=0;//滑窗 右边界索引

        int cursum=nums[0];//记录当前滑窗和
        int maxsum=nums[0];

        while(left<=right&&rightcursum?maxsum:cursum;//根据大小关系 关系maxsum
        }
        return maxsum;
    }
};
  • 对于子串的操作

滑动窗口算法思想图解说明_第8张图片

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left = 0, right = 0;
        unordered_map window;//创建哈希表存储 方便统计重复元素
        int res = 0; // 记录最长长度

        while (right < s.size()) {
            char c1 = s[right];
            window[c1]++;
            right++;
            // 如果 window 中出现重复字符
            // 开始移动 left 缩小窗口
            while (window[c1] > 1) {
                char c2 = s[left];
                window[c2]--;
                left++;
            }
            res = max(res, right - left);//根据当前滑窗边界差值长度对res进行更新
        }
    return res;
    }
};

举例说明:“pwwkew”

滑动窗口算法思想图解说明_第9张图片

你可能感兴趣的:(算法)