Map<Character, Integer> window = new HashMap<>();
int res = 0;
int left = 0, right = 0;
while (right < s.length()) {
char c = s.charAt(right);
right++;
window.put(c, window.getOrDefault(c, 0) + 1);
// 收缩 left 边界
while (window.get(c) > 1) {
char removed = s.charAt(left);
left++;
window.put(removed, window.getOrDefault(removed, 0) - 1);
}
res = Math.max(res, right - left);
}
模板1-固定长度窗口
// 固定长度窗口: 窗口收缩靠的是左右边界值 和 t.length()
void slidingWindow(String s, String t) {
HashMap<Character, Integer> window = new HashMap<>();
HashMap<Character, Integer> need = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
need.put(t.charAt(i), need.getOrDefault(t.charAt(i), 0) + 1);
}
// TODO: result
int left = 0, right = 0;
int valid = 0;
while (right < s.length()) {
char c = s.charAt(right);
right++;
// 进行窗口内数据的一系列更新
if (need.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) + 1);
if (window.get(c).equals(need.get(c))) {
valid++;
}
}
// 窗口收缩靠左右边界指针
while (right - left >= t.length()) {
// valid: 判断收割结果
if (valid == need.keySet().size()) {
// TODO: 收割结果
}
// d 是将移出窗口的字符
char removed = s.charAt(left);
left++;
// 进行窗口内数据的一系列更新
if (need.containsKey(removed)) {
if (window.get(removed).equals(need.get(removed))) {
valid--;
}
window.put(removed, window.getOrDefault(removed, 0) - 1);
}
}
}
}
模板2-不固定长度窗口
// 不固定长度窗口: 窗口收缩靠 valid 与 need.size()
void slidingWindow(String s, String t) {
// part-1: init template
Map<Character, Integer> need = new HashMap<>();
Map<Character, Integer> window = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
need.put(t.charAt(i), need.getOrDefault(t.charAt(i), 0) + 1);
}
// TODO: result variable
int valid = 0;
int left = 0, right = 0;
while (right < s.length()) {
// part-2-1: move right
char c = s.charAt(right);
right++;
// part-2-2: add value to window and valid
if (need.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) + 1);
if (window.get(c).equals(need.get(c))) {
valid++;
}
}
// part-3: move left continue
// 收缩 left 边界
while (valid == need.keySet().size()) {
// TODO: 收割结果
// part-4: collect result
// part-5-1: move left
char removed = s.charAt(left);
left++;
// part-2-2: remove value from window and valid
if (need.containsKey(removed)) {
if (window.get(removed).equals((need.get(removed)))) {
valid--;
}
window.put(removed, window.getOrDefault(removed, 0) - 1);
}
}
}
}
滑动窗口
求满足某种条件的最短或最长子数组[子串]
使用场景
步骤
定长的窗口
||不定长的窗口{最大/小/长/短}
{窗口内的满足条件的值}
与need一起
模板0
模板1-固定长度窗口
模板2-不固定长度窗口
list