|
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