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).windows
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".数组
Note:
If there is no such window in S that covers all characters in T, return the empty string "".指针
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.code
头尾指针遍历的思路。先遍历尾指针,找到所有t覆盖,而后移动头指针找到最小的子串,比较是不是当前最小。
而后继续移动一次头指针后,去掉一个有效字符,从新开始一轮的循环。ip
为了方便记录是否已经找到所有的,对t用一个字符频次数组来计数,找到一个队频次减一。为了方便观察数组是否所有覆盖,另外维护一个有效减位的计数,当计数达到t的长度时就是一次彻底覆盖。而后再查找最小覆盖时,若是是无效字符,或者是有效但多出来频次的字符都继续跳过。string
耗时:9msit
class Solution { public: // 字符的值域空间是128,用128位的数组表示t中每一个字符出现的次数 // 头、尾两个指针。尾指针一直向前扫描,直到覆盖所有的t,假设指向i。 // 而后头指针向后移动,直到找到以i结尾的最小长度。 // 记录下当前的是不是最小子串。而后继续尾指针、头指针的这种扫描方式。 string minWindow(string s, string t) { if (s.length() == 0 || t.length() == 0) { return ""; } int start = 0; int end = 0; int min_len = s.length() + 1; int cur_start = 0; int cur_end = 0; int t_freq[128]; bool t_exist[128]; bzero(t_freq, sizeof(t_freq)); bzero(t_exist, sizeof(t_exist)); for (int i = 0; i < t.length(); i++) { char ch = t[i]; t_freq[ch]++; t_exist[ch] = true; } int ls = s.length(); int lt = t.length(); int cnt = 0; // 记录须要的字符出现过多少次,方便判断是否已经包含所有的t while (cur_end < ls) { char ch = s[cur_end]; if (!t_exist[ch]) { cur_end++; continue; } if (t_freq[ch] > 0) { cnt++; } t_freq[ch]--; cur_end++; if (cnt == lt) { while (cur_start < cur_end) { char ch = s[cur_start]; if (!t_exist[ch]) { cur_start++; continue; } if (t_freq[ch] < 0) { t_freq[ch]++; cur_start++; continue; } else { // find one candidate substr int cur_len = cur_end - cur_start; if (cur_len < min_len) { min_len = cur_len; start = cur_start; end = cur_end; } cnt--; t_freq[ch]++; cur_start++; break; } } } } if (min_len <= ls) { return s.substr(start, min_len); } else { return ""; } } };