forked from neetcode-gh/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
0076-minimum-window-substring.js
78 lines (58 loc) · 1.96 KB
/
0076-minimum-window-substring.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* https://leetcode.com/problems/minimum-window-substring/
* Time O(N + M) | SpaceO(N + M)
* @param {string} s
* @param {string} t
* @return {string}
*/
var minWindow = function (s, t) {
const isMissingArgs = !s.length || !t.length;
if (isMissingArgs) return '';
const frequencyMap = getFrequencyMap(t);
const { start, end } = getWindowPointers(s, t, frequencyMap);
return getSubString(s, start, end);
};
const getFrequencyMap = (str, frequencyMap = new Map()) => {
for (const char of str) {
frequencyMap.set(char, (frequencyMap.get(char) || 0) + 1);
}
return frequencyMap;
};
const getWindowPointers = (s, t, frequencyMap) => {
let [left, right, matched, start, end] = [0, 0, 0, 0, s.length + 1];
while (right < s.length) {
matched = addRightFrequency(s, right, frequencyMap, matched);
const canSlide = () => matched === t.length;
while (canSlide()) {
const window = right - left + 1;
const isSmaller = window < end;
if (isSmaller) {
[start, end] = [left, window];
}
matched = subtractLeftFrequency(s, left, frequencyMap, matched);
left++;
}
right++;
}
return { start, end };
};
const addRightFrequency = (s, right, frequencyMap, matched) => {
const char = s[right];
if (frequencyMap.has(char)) {
frequencyMap.set(char, frequencyMap.get(char) - 1);
const isInWindow = 0 <= frequencyMap.get(char);
if (isInWindow) matched++;
}
return matched;
};
const subtractLeftFrequency = (s, left, frequencyMap, matched) => {
const char = s[left];
if (frequencyMap.has(char)) {
const isOutOfWindow = frequencyMap.get(char) === 0;
if (isOutOfWindow) matched--;
frequencyMap.set(char, frequencyMap.get(char) + 1);
}
return matched;
};
const getSubString = (s, start, end) =>
end <= s.length ? s.slice(start, start + end) : '';