个人主页:敲上瘾-CSDN博客
目录
一.滑动窗口算法原理:
滑动窗口可以说是一种特殊双指针算法,即它同样用两个指针实现。**滑动窗口:用一个left指针和right指针来维护一段区间即[left, right],也可称为窗口,right右移即进窗口,left右移即出窗口。**即通常情况下left和right指针都是同向移动的。对于滑动窗口我们主要关心以下几点:
++进窗口,出窗口,更新结果。进窗口肯定是在出窗口前进行的,而什么时候更新结果因题而异。++
其实对于滑动窗口本身还是挺简单的,难点在我们能不能想到使用滑动窗口,接下来我准备了三个题,每题都分为三个步骤:题目解析,算法原理,代码编写。从最普通的暴力解法过渡到滑动窗口。最后来做总结。
二.无重复字符的最长子串
1.题目解析

该题需要我们求出字符串s内无重复字符的最长子串,注意这里子串的意思也就是在字符串s内连续的一段字符,所以在求解该题时最好不要对原字符串进行改动。
2.算法原理
明显这道题很容易想到的就是暴力枚举,但是时间复杂度比较高是过不了该题的测试的。在我们没能想到其他解法时,可以这样做,去分析暴力解法,从暴力解法中找到优化的规律。如下:

按以上方法把整个数组遍历完可以解决这个题目,但可以做以下优化:

这就是一个滑动窗口,把[left, right]区间当作一个窗口存放的是不重复的子串,然后用一个len变量来记录窗口的最大长度,当right滑动到字符串结尾时也就把所有的情况都记录了一遍,此时结束循环返回len该算法就完成了。
注意:这里因为要检查字符是否重复所以用一个哈希表来记录窗口内数据出现的个数可以提高效率。
3.代码编写
cpp
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
if(s.size()==0) return 0;
int len=-1;
int arr[127]={0};
for(int left=0,right=0;right<s.size();right++)
{
arr[s[right]]++;
cout<<arr[s[right]]<<' ';
while(arr[s[right]]==2)
{
arr[s[left++]]--;
}
if(len<right-left+1) len=right-left+1;
}
return len;
}
};
三.长度最小的子数组
1.题目解析

本题要求子数组(即数组内的一段连续的元素)的元素之和大于等于target的最小长度,如果不存在返回0。例如示例1,[2,3,1,2,4,3]中子数组大于等于target的子数组有:
2,3,1,2\],\[2,3,1,2,4\],\[2,3,1,2,4,3\],\[3,1,2,4\],
\[3,2,1,4,3\],\[1,2,4\],\[1,2,4,3\],\[2,4,3\],\[4,3\]。
而长度最小的子数组为\[4,3\],长度为2,以上所列的子数组是一个模拟暴力枚举的结果。
### 2.算法原理
该题可以使用暴力枚举(即两个循环解决)时间复杂度为O(N\^2)。对于暴力解法在这里就不再多讲,现在我们可以试图从暴力解法中寻找规律并进行优化。如下:

以上我们分析的结果就是一个滑动窗口算法,left,right来维护这个窗口,left右移即出窗口,right右移即进窗口,当窗口里的元素之和大于等于target时更新最小长度。直到right滑动到数组结尾可得到答案。时间复杂度为O(N)。
### 3.代码编写
```cpp
class Solution
{
public:
int minSubArrayLen(int target, vector