Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = “ADOBECODEBANC”, T = “ABC” Output: “BANC” Note:
If there is no such window in S that covers all characters in T, return the empty string “”. If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
Solution:
create counter for target string, know how many for each char
walk through array with start, end pointers
use independent variable target_len to know if we have all char in t
when find s[end] is needed, subtract target_len
when target_len is 0, means current window contains every letter in t, check if it’s smaller than existed res
classSolution: defminWindow(self, s:str, t:str) -> str: target = Counter(t) start, end = 0, 0 res = "" target_len = len(t) for end in range(len(s)): if target[s[end]] > 0: target_len -= 1 target[s[end]] -= 1 while target_len == 0: ifnot res or len(res) > len(s[start:end+1]): res = s[start:end+1] target[s[start]] += 1 if target[s[start]] > 0: target_len += 1 start += 1 return res
Solution C++
Since we need to solve this problem in $O(n)$, so we can not use brute force or sorting. We can use a hash table with characters that appeared in T as key, and number of appearance as value.
walk through T, store in map
walk through S. If meet a character c appeared in T, map[c]–. Keep going until we have a window that contains every character in T.
Move the left boundary of the window, skip characters that do not exist in T. Skip a character if it appears in S more that appears in T. example: S: aaaabb T: ab
classSolution { public: stringminWindow(string S, string T){ if (T.size() > S.size()) return""; string res = ""; int left = 0, count = 0, minLen = S.size() + 1; unordered_map<char, int> m; for (int i = 0; i < T.size(); ++i) { if (m.find(T[i]) != m.end()) ++m[T[i]]; else m[T[i]] = 1; } for (int right = 0; right < S.size(); ++right) { if (m.find(S[right]) != m.end()) { //found a character appeared in both S and T --m[S[right]]; if (m[S[right]] >= 0) ++count; while (count == T.size()) { //find a valid window that contains every characters in T if (right - left + 1 < minLen) { minLen = right - left + 1; res = S.substr(left, minLen); } if (m.find(S[left]) != m.end()) { ++m[S[left]]; //s[left] is a char in T if (m[S[left]] > 0) --count; } ++left; } } } return res; } };