O(n) 想象成柱状图,每个字母频数是一个柱,先把t中的字母频数加上去,然后r指针遍历s每个字符(扩大窗口),先减小各个字母的频数,然后l指针再二次遍历每个字符(缩小窗口)同时增大各个字母的频数直到恢复为正
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
| class Solution { public: string minWindow(string s, string t) { int f[128] = {0}; for (char c : t) { ++f[c]; } int n = s.length(), m = t.length(), ll = -1, rr = n; for (int r = 0, l = 0, cnt = 0; r < n; ++r) { if (--f[s[r]] >= 0) { ++cnt; } while (cnt == m) { if (r - l < rr - ll) { ll = l; rr = r; } if (++f[s[l++]] > 0) { --cnt; } } } return ll == -1 ? "" : s.substr(ll, rr + 1 - ll); } };
|
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
| class Solution { public: string minWindow(string s, string t) { int smap[256] = {0}, tmap[256] = {0}; for (const auto &c : t) { ++tmap[c]; } string res; int n = s.length(), window = INT_MAX; for (int i = 0, j = i; i < n; ++i) { while (j < n && !contains(smap, tmap)) { ++smap[s[j++]]; } if (contains(smap, tmap) && j - i < window) { window = j - i; res = s.substr(i, window); } --smap[s[i]]; } return res; }
bool contains(int smap[], int tmap[]) { for (int i = 0; i < 256; ++i) { if (smap[i] < tmap[i]) { return false; } } return true; } };
|