diff --git a/.vscode/settings.json b/.vscode/settings.json
index f139b9e..4c3c287 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,6 @@
{
"cSpell.words": [
+ "ADOBECODEBANC",
"Gitpod",
"LVIII",
"Paddr",
diff --git a/README.md b/README.md
index 8b62ab9..421420b 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,11 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
- LeetCode 1371. 每个元音包含偶数次的最长子字符串
+- [最小覆盖子串](src/string/minimum-window-substring.js)
+
+ - LeetCode 76. 最小覆盖子串
+ -LintCode 1420. 最小覆盖子串II
+
## 数组/队列/集合/映射
- [电话号码的字母组合](src/array/letter-combinations-of-a-phone-number.js)
diff --git a/src/string/minimum-window-substring.js b/src/string/minimum-window-substring.js
new file mode 100644
index 0000000..bdbf941
--- /dev/null
+++ b/src/string/minimum-window-substring.js
@@ -0,0 +1,40 @@
+/**
+ * @param {string} s
+ * @param {string} t
+ * @return {string}
+ */
+export const minWindow = function (s, t) {
+ const sLen = s.length; const tLen = t.length
+ const tMap = new Map(); const map = new Map()
+ let l = 0; let r = 0; let res = ''
+
+ for (let i = 0; i < tLen; i++) {
+ tMap.set(t[i], (tMap.get(t[i]) || 0) + 1)
+ }
+
+ const check = (cMap) => {
+ const check = new Map(
+ [...cMap].filter(([k, v]) => tMap.has(k) && v >= tMap.get(k))
+ )
+
+ return check.size === tMap.size
+ }
+
+ while (r <= sLen) {
+ if (t.includes(s[r])) {
+ map.set(s[r], (map.get(s[r]) || 0) + 1)
+ }
+
+ while (check(map) && l <= r) {
+ const tmp = s.slice(l, r + 1)
+ if (res.length === 0 || tmp.length <= res.length) res = tmp
+ if (t.includes(s[l]) && map.has(s[l])) {
+ map.set(s[l], map.get(s[l]) - 1)
+ }
+ l++
+ }
+ r++
+ }
+
+ return res
+}
diff --git a/test/string/minimum-window-substring.test.js b/test/string/minimum-window-substring.test.js
new file mode 100644
index 0000000..6d7e360
--- /dev/null
+++ b/test/string/minimum-window-substring.test.js
@@ -0,0 +1,9 @@
+import { minWindow } from '../../src/string/minimum-window-substring'
+
+test('最小覆盖子串', () => {
+ expect(minWindow('ab', 'a')).toBe('a')
+ expect(minWindow('ADOBECODEBANC', 'ABC')).toBe('BANC')
+ expect(minWindow('a', 'a')).toBe('a')
+ expect(minWindow('a', 'aa')).toBe('')
+ expect(minWindow('abcdc', 'da')).toBe('abcd')
+})