滑动窗口法:不断调节子序列的起始位置和终止位置,其实是双指针,但看起来像是一个窗口在不断滑动。
一、LeetCode题 209.长度最小的子数组 209. 长度最小的子数组 - 力扣(LeetCode)
题目描述:总和大于等于,长度最小,连续子数组
窗口:满足其和大于等于目标值长度最小的连续子数组。
窗口起始位置:当当前窗口值大于目标值之后 , 需要向前移动
窗口终止位置:遍历数组的指针 , 即for循环的索引
代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT_MAX;
int i = 0; // 滑动窗口起始位置
int sum = 0; //当前窗口内元素的总和
int subLength = 0; //连续子数组的长度
for (int j = 0; j < nums.size(); j++) {
// j 为滑动窗口的终止位置
sum += nums[j];
while (sum >= target) {
subLength = j - i + 1; //保存符合条件的子数组的长度
result = min(result, subLength); //判断当前子数组是否长度最小
sum -= nums[i]; //关键:更新滑动窗口起始位置
i++;
}
}
return result == INT_MAX ? 0 :result;
}
};
1、INT_MAX 和 INT_MIN 是 C++ 中的两个宏,代表了整型变量能够存储的最大正整数和最小负整数,分别为 2147483647 和 -2147483648,在头文件 <limits.h> 中定义。
2、三目运算符:1 ? 2 : 3 若1为真,执行返回2,若1为假,执行返回3。
二、LeetCode题 904. 水果成篮 904. 水果成篮 - 力扣(LeetCode)
题目描述:寻找只有两个不同元素的最长连续子数组
代码:关键是想清窗口起始位置和终止位置的更新规则。
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int i = 0; //滑动窗口起始位置
int result = 0; //能够采集水果的最大数目
int subLength = 0; //保存每个窗口内采集水果的数目
int right = 0, left = 0, k = 0;
if(fruits.size() < 3) return fruits.size();
for (int j = 0; j < fruits.size(); j++) {
for(k = i; k < fruits.size(); k++){
// 找到第二个水果种类,保存索引和大小
if(fruits[k] != fruits[i]){
right = fruits[k];
left = k;
break;
}
// 整个数组只有一个数的情况
else if(k == fruits.size() - 1) return k - i + 1;
}
while(fruits[k] == fruits[i] || fruits[k] == right){
// 当种类符合时,不断向右滑动窗口
subLength = k - i + 1;
result = max(result, subLength);
if(k == fruits.size() - 1) return result;
k++;
}
// 种类不符合时,更新起始位置至保存的第二个水果种类起始位置
i = left;
}
return result;
}
};
本文根据代码随想录顺序刷题。代码随想录 (programmercarl.com)