|
1 | 1 | #include <stdio.h>
|
2 | 2 | #include <stdlib.h>
|
3 | 3 | #include <string.h>
|
4 |
| -#include <limits.h> |
5 | 4 |
|
6 | 5 | static char *minWindow(char *s, char *t)
|
7 | 6 | {
|
8 |
| - /* |
9 |
| - * Declare two "hash map" for ASCII chars |
10 |
| - * f[]: represents the char found in s |
11 |
| - * m[]: stores the chars in t |
12 |
| - */ |
13 |
| - int i, f[256], m[256], pat_len = 0; |
14 |
| - memset(m, 0, sizeof(m)); |
15 |
| - memset(f, 0, sizeof(f)); |
16 |
| - |
17 |
| - /* |
18 |
| - * Go through t, and inital the m[] and f[] |
19 |
| - * Notes: duplicate char is allowed. |
20 |
| - */ |
21 |
| - for (i = 0; t[i] != '\0'; i++) { |
22 |
| - m[t[i]]++; |
23 |
| - pat_len++; |
| 7 | + int i, j, count[256] = { 0 }; |
| 8 | + int slen = strlen(s); |
| 9 | + int tlen = strlen(t); |
| 10 | + for (i = 0; i < tlen; i++) { |
| 11 | + count[t[i]]++; |
24 | 12 | }
|
25 | 13 |
|
26 |
| - int start =-1; |
27 |
| - int size = INT_MAX; |
28 |
| - int found = 0; |
29 |
| - int begin = 0; |
30 |
| - for (i = 0; s[i] != '\0'; i++) { |
31 |
| - /* First, find the right side of the window which should be in t */ |
32 |
| - if (m[s[i]] > 0) { |
33 |
| - /* if one char has been found enough times, then do not do found++ */ |
34 |
| - if (++f[s[i]] <= m[s[i]]) { |
35 |
| - found++; |
36 |
| - } |
| 14 | + /* edges of sliding window */ |
| 15 | + int lo = 0, hi = 0; |
| 16 | + int min_len = slen + 1; |
| 17 | + int start = 0; |
| 18 | + int chars_to_meet = tlen; |
| 19 | + while (hi < slen) { |
| 20 | + if (--count[s[hi++]] >= 0) { |
| 21 | + /* pattern found */ |
| 22 | + chars_to_meet--; |
| 23 | + } |
37 | 24 |
|
38 |
| - /* the right side of the window is confirmed as i */ |
39 |
| - /* The found counter will no more increase if the first right side of the window is confirmed, |
40 |
| - * the next step run here can also be regarded as a new right side of a new window. */ |
41 |
| - if (found == pat_len) { |
42 |
| - /* Then we need to find the left side of the window |
43 |
| - * 1) m[s[begin]] == 0 => Both left and right side should be found in t |
44 |
| - * 2) f[s[begin]] > m[s[begin]] => duplicate chars are more than excepted in the window so that we can even shrink the size. */ |
45 |
| - while (m[s[begin]] == 0 || f[s[begin]] > m[s[begin]]) { |
46 |
| - if (f[s[begin]] > m[s[begin]]) { |
47 |
| - f[s[begin]]--; |
48 |
| - } |
49 |
| - begin++; |
50 |
| - } |
| 25 | + while (chars_to_meet == 0) { |
| 26 | + if (hi - lo < min_len) { |
| 27 | + min_len = hi - lo; |
| 28 | + start = lo; |
| 29 | + } |
51 | 30 |
|
52 |
| - /* Calculate the minimized window size */ |
53 |
| - if (size > i - begin + 1) { |
54 |
| - start = begin; |
55 |
| - size = i - begin + 1; |
56 |
| - } |
| 31 | + /* Chars with negative count are not included in the pattern string */ |
| 32 | + if (++count[s[lo++]] > 0) { |
| 33 | + /* chars_to_meet == 1 */ |
| 34 | + chars_to_meet++; |
57 | 35 | }
|
58 | 36 | }
|
59 | 37 | }
|
60 | 38 |
|
61 | 39 | char *result;
|
62 |
| - if (start >= 0 && size > 0) { |
63 |
| - result = malloc(size + 1); |
64 |
| - memcpy(result, s + start, size); |
65 |
| - result[size] = '\0'; |
| 40 | + if (min_len <= slen) { |
| 41 | + result = malloc(min_len + 1); |
| 42 | + memcpy(result, s + start, min_len); |
| 43 | + result[min_len] = '\0'; |
66 | 44 | } else {
|
67 | 45 | result = malloc(1);
|
68 | 46 | result[0] = '\0';
|
69 | 47 | }
|
| 48 | + |
70 | 49 | return result;
|
71 | 50 | }
|
72 | 51 |
|
|
0 commit comments