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).
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 emtpy string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
題目的意思是:
給出兩個字串S和T,求S的最小子串(或者最小字元視窗),該子串包含所有T的字元。要求線上性時間內完成。如果沒有符合要求的子串,則返回“”。如果有多個滿足條件的最小子串,則返回第一個。
解題思路:
由於題目要求線上性時間內完成,就要減少T的字元的查詢時間,故要考慮用hashMap。hashMap的查詢時間複雜度是O(1)。由於目標串T可能含有重複字元,因此使用一個雜湊表記錄目標串的字元和字元出現的次數,同時要記錄搜尋視窗的已匹配的字元數count,最小字元視窗的開始位置start,已匹配的字元和次數findHashMap.
當已匹配的總字元數大於目標串的字元數時,即count > tLen時,要儘可能的把視窗的開始位置往後移動,即start前移,使視窗儘可能的小。
在移動視窗位置時必須滿足的條件:
(1)當前字元不在目標串T裡
(2)已匹配的次數大於目標串裡相應字元出現的次數
注意特殊情況的處理
(1)兩個字串都為空的時候
(2)S的長度<T的長度
(3)S字元都不在T裡面時start的處理
class Solution { public: string minWindow(string S, string T) { if(S == "" || T == "" ||S.length() < T.length()) return ""; int sLen =S.length(), tLen = T.length(); unordered_map<char,int> hashMap; for(int i = 0 ; i < tLen; ++ i) hashMap[T[i]]++; unordered_map<char,int> findHashMap; int count = 0, start =0, minLen = INT_MAX,minLenStart = -1; for(int i = 0 ; i < sLen; ++ i){ char ch = S[i]; if(hashMap.find(ch)==hashMap.end()) continue; findHashMap[ch]++; if(findHashMap[ch] <= hashMap[ch]) count++; if(count>=tLen){ char c = S[start]; while(findHashMap.find(c) == findHashMap.end() || findHashMap[c] > hashMap[c] ){ if(findHashMap.find(c)!=findHashMap.end()) findHashMap[c]--; start++; c = S[start]; } int len = i-start+1; if(len < minLen){ minLen = len; minLenStart = start; } } } if(minLenStart == -1)return ""; else return S.substr(minLenStart,minLen); } };