← Back to table of contents

Minimum Window Substring (Characters)

Brute-force sliding window

TimeO(n² · m) to O(n³)SpaceO(m)Suboptimal
Re-scans the current window for every move (testSegment + countCharacters). Many overlapping windows are re-checked from scratch, leading to cubic behavior in the worst case.

Code

1function countCharacters(string: string, character: string) {
2    const count = string.match(new RegExp(character, 'g'))?.length || 0;
3    return count;
4}
5
6function objectify(string: string) {
7    return string.split('').reduce((acc, char) => {
8        acc[char] = (acc[char] || 0) + 1;
9        return acc;
10    }, {} as Record<string, number>)
11}
12
13function testSegment(segment: string, required: string) {
14    const found = objectify(required);
15    Object.keys(found).forEach(char => {
16        found[char] -= countCharacters(segment, char);
17    });
18    return Object.values(found).every(count => count <= 0);
19}
20
21function minWindow(text: string, required: string): string {
22    let left = 0;
23    let right = 0;
24    let minLength = Infinity;
25    let minStart = 0;
26
27    while (right < text.length) {
28        if (testSegment(text.slice(left, right + 1), required)) {
29            if (right - left + 1 < minLength) {
30                minLength = right - left + 1;
31                minStart = left;
32            }
33            left++;
34        } else {
35            right++;
36        }
37    }
38
39    return minLength === Infinity ? '' : text.slice(minStart, minStart + minLength);
40}
41
42

Animation

textADOBECODEBANC
requiredABC
left
right
Best window: —
Speed: