PS:以下代码皆为C++代码实现
1.什么是滑动窗口
假设有两个同向指针,一个左指针,一个右指针,右指针在移动的同时。左指针不变,当到达判断条件的时候,左指针开始移动,左右指针形成一个窗口,当左右指针移动的时候,窗口移动,这就是滑动窗口问题。做这种题基本思路为:
- 判断进窗口位置
- 判断出窗口位置
- 返回结果
2.题目
2.1 长度最小的子数组 力扣
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。示例 2:
输入:target = 4, nums = [1,4,4]
输出:1示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-size-subarray-sum
class Solution {
public:
int minSubArrayLen(int target, vector& nums)
{
int sum=0,len=INT_MAX;
int n=nums.size();
for(int left=0,right=0;right=target)//判断条件+维护
{
sum-=nums[left];
len=min(len,right-left+1);//返回结果
left++;
}
}
return len==INT_MAX?0:len;//返回结果
}
};
2.2 无重复字符的最长字串 力扣
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int len=0;
int n=s.size();
int hash[128]={0};
for(int left=0,right=0;right1)//判断条件
{
hash[s[left]]--;
left++;//出窗口
}
len=max(len,right+1-left);//更新结果
}
return len;//返回值
}
};
2.3 最大连续1的个数3 力扣
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
示例 1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。示例 2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/max-consecutive-ones-iii
class Solution {
public:
int longestOnes(vector& nums, int k)
{
int n=nums.size();
int ZenoNum=0;
int count=0;
for(int left=0,right=0;rightk)//判断条件
{
if(nums[left]==0)
{
ZenoNum--;//出窗口条件
}
left++;
}
count=max(count,right+1-left); //更新结果
}
return count;
}
};
2.4 将x减到0的最小操作数 力扣
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
示例 1:
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。示例 2:
输入:nums = [5,6,7,8,9], x = 4
输出:-1示例 3:
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero
class Solution {
public:
int minOperations(vector& nums, int x)
{
//反向求最长的操作数,然后减去最长操作数的长度
int n=nums.size();
int target=0;
int sum=0;
for(auto sh:nums) sum+=sh;
int len=-1;
if((sum-x)<0) return -1;
for(int left=0,right=0;right(sum-x))//进窗口
{
target-=nums[left];
//出窗口
left++;
}
if(target==(sum-x))//等于更新
len=max(len,right-left+1);
}
if((n-len)>n) return -1;
return n-len;
}
};
2.5 找到所有字符串中的异位词 力扣
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。示例 2:
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string
class Solution {
public:
vector findAnagrams(string s, string p)
{
int hash1[26]={0};
for(auto ch: p) hash1[ch-'a']++;//统计字符串中出现的字符个数
int n=p.size();
int hash2[26]={0};
vector ret;
for(int left=0,right=0,count=0;rightn)
{
char out=s[left];
left++;
if(hash2[out-'a']--<=hash1[out-'a'])//出窗口+维护
{
//hash2[s[left]-'a']--;
count--;
}
}
if(n==count) ret.push_back(left);
}
return ret;
}
};