Algorithms first
最小覆盖子串 · 交互式算法学习
找到覆盖 t 全部字符的最短子串。
#76 · 滑动窗口
最小覆盖子串
Minimum Window Substring
s = "ADOBECODEBANC", t = "ABC"线性序列4 个关键状态
步骤 1右端到 C 时 missing 归零。
best=6A
0D
1O
2B
3E
4C
5O
6D
7E
8B
9A
10N
11C
12推荐
有效字符计数滑窗
时间
O(n)空间 O(字符集)右端补充字符;覆盖完成后移动左端,直到刚好失去覆盖。
1function minWindow(s, t) {2 const need = new Map();3 for (const c of t) need.set(c, (need.get(c) || 0) + 1);4 let missing = t.length,5 l = 0,6 start = 0,7 best = Infinity;8 for (let r = 0; r < s.length; r++) {9 if ((need.get(s[r]) || 0) > 0) missing--;10 need.set(s[r], (need.get(s[r]) || 0) - 1);11 while (missing === 0) {12 if (r - l + 1 < best) {13 best = r - l + 1;14 start = l;15 }16 need.set(s[l], (need.get(s[l]) || 0) + 1);17 if (need.get(s[l]) > 0) missing++;18 l++;19 }20 }21 return best === Infinity ? '' : s.slice(start, start + best);22}多语言参考
来源 · CC BY-SA 4.0 ↗Java · C++ · Go
这是一组同题正确实现,独立于上方当前动画方法;不同语言可能采用另一种正确策略。
1class Solution {2 public String minWindow(String s, String t) {3 int[] need = new int[128];4 int[] window = new int[128];5 for (char c : t.toCharArray()) {6 ++need[c];7 }8 int m = s.length(), n = t.length();9 int k = -1, mi = m + 1, cnt = 0;10 for (int l = 0, r = 0; r < m; ++r) {11 char c = s.charAt(r);12 if (++window[c] <= need[c]) {13 ++cnt;14 }15 while (cnt == n) {16 if (r - l + 1 < mi) {17 mi = r - l + 1;18 k = l;19 }20 c = s.charAt(l);21 if (window[c] <= need[c]) {22 --cnt;23 }24 --window[c];25 ++l;26 }27 }28 return k < 0 ? "" : s.substring(k, k + mi);29 }30}交互式算法学习
从执行步骤真正理解 LeetCode 经典 150
本站整理 150 道高频算法面试题和 302 种解法。动画方法同步展示 JavaScript 与 Python;每题另提供 Java、C++ 与 Go 同题参考实现。
AlgoViz Lab
最小覆盖子串 · 解法对比
找到覆盖 t 全部字符的最短子串。
- 测试用例
s = "ADOBECODEBANC", t = "ABC"- 题目分类
- 滑动窗口
- 解法对比
- 2
枚举所有子串
对每个左端逐步扩张右端并检查是否覆盖。
- 时间
O(n²·字符集)- 空间
O(字符集)
有效字符计数滑窗
右端补充字符;覆盖完成后移动左端,直到刚好失去覆盖。
- 时间
O(n)- 空间
O(字符集)