[Algo] 滑动窗口
1. 长度最小的子数组
// 1. 长度最小的子数组
// https://leetcode.cn/problems/minimum-size-subarray-sum/description/
int minSubArrayLen(int target, vector<int>& nums) {
int ans = INT32_MAX;
for (int l = 0, r = 0, sum = 0; r < nums.size(); r++)
{
sum += nums[r];
while (sum - nums[l] >= target) sum -= nums[l++];
if (sum >= target) ans = min(ans, r - l + 1);
}
return ans == INT32_MAX ? 0 : ans;
}
2. 无重复字符的最长子串
// 2. 无重复字符的最长子串
// https://leetcode.cn/problems/longest-substring-without-repeating-characters/
int lengthOfLongestSubstring(string str) {
int ans = 0;
set<char> s;
bool flag;
for (int l = 0, r = 0; r < str.length(); r++)
{
if (s.find(str[r]) != s.end()) flag = true;
else flag = false;
if (flag)
{
while (str[l] != str[r]) s.erase(str[l++]);
s.erase(str[l++]);
}
s.insert(str[r]);
ans = max(ans, r - l + 1);
}
return ans;
}
3. 最小覆盖子串
// 3. 最小覆盖子串
// https://leetcode.cn/problems/minimum-window-substring/description/
string minWindow(string s, string t) {
int arr[256] = {0};
for (int i = 0; i < t.length(); i++) arr[t[i]]--;
int debt = t.length();
int len = INT32_MAX, start = 0;
for (int l = 0, r = 0; r < s.length(); r++)
{
if (arr[s[r]]++ < 0) debt--;
if (debt == 0)
{
while (arr[s[l]] > 0) arr[s[l++]]--;
if (r - l + 1 < len)
{
len = r - l + 1;
start = l;
}
}
}
if (len == INT32_MAX) return "";
return s.substr(start, len);
}
4. K个不同整数的子数组
int subarraysWithNoMoreThanKDistinct(vector<int>& nums, int k);
// 4. K个不同整数的子数组
// https://leetcode.cn/problems/subarrays-with-k-different-integers/
int subarraysWithKDistinct(vector<int>& nums, int k) {
return subarraysWithNoMoreThanKDistinct(nums, k) - subarraysWithNoMoreThanKDistinct(nums, k - 1);
}
int subarraysWithNoMoreThanKDistinct(vector<int>& nums, int k)
{
int arr[20001] = {0};
int cnt = 0, ans = 0;
for (int l = 0, r = 0; r < nums.size(); r++)
{
if (++arr[nums[r]] == 1) cnt++;
while (cnt > k)
{
if (--arr[nums[l++]] == 0) cnt--;
}
ans += r - l + 1;
}
return ans;
}
5. 至少有K个重复字符的最长子串
// 5. 至少有K个重复字符的最长子串
// https://leetcode.cn/problems/longest-substring-with-at-least-k-repeating-characters/description/
int longestSubstring(string s, int k) {
int ans = 0;
for (int require = 1; require <= 26; r++)
{
// require 种字符
int arr[256] = {0};
for (int l = 0, r = 0, collect = 0, satisfy = 0; require < s.length(); r++)
{
// collect 总收集到的字符种数, satisfy 满足条件的字符种数
arr[s[r]]++;
if (arr[s[r]] == 1) collect++;
if (arr[s[r]] == k) satisfy++;
while (collect > require)
{
if (arr[s[l]] == 1) collect--;
if (arr[s[l]] == k) satisfy--;
arr[s[l++]]--;
}
if (satisfy == require) ans = max(ans, r - l + 1);
}
}
return ans;
}