Minimum Window Substring
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.
由於大小寫字母的ASCII碼不大於128,因此開辟兩個數組存儲信息。
needFind數組存儲T字符串每個字符出現次數。例如:needFind['A']=5意為T中A出現5次。
Found數組存儲S字符串在[begin,end]窗口內每個字符出現次數。
算法核心思想如下:
在保證[begin,end]窗口包含T中所有字符的條件下,延伸end,收縮begin。
進行一次掃描后,記錄符合條件的最小窗口(end-begin+1)表示的字符串。
有個問題:怎樣才知道[begin,end]窗口包含了T中所有字符?
我使用count記錄剩余“有效”字符數,當count達到0時,即可說明[begin,end]包含了T。
注意:“有效”的意思是指,當前延伸得到的S[end]字符,使得[begin,end]更進一步包含T,而不是重復勞動。
比如說,T="a", [begin,end]已經包含"a",再延伸得到"aa",只是無效操作,並沒有使得[begin,end]更接近T,有效字符數仍為1.
class Solution { public: string minWindow(string S, string T) { int begin = 0; int end = 0; int minbegin = 0; int minend = 0; int minSize = INT_MAX; vector<int> needFind(128, 0); vector<int> Found(128, 0); for(int i = 0; i < T.size(); i ++) needFind[T[i]] ++; Found[S[0]] ++; int count = T.size(); if(needFind[S[0]] >= Found[S[0]]) count --; while(true) { if(count == 0) {//shrink begin while(Found[S[begin]] > needFind[S[begin]]) { Found[S[begin]] --; begin ++; } int size = end-begin+1; if(size < minSize) { minbegin = begin; minend = end; minSize = size; } } if(end < S.size()) { end ++; Found[S[end]] ++; if(needFind[S[end]] >= Found[S[end]]) count --; } else break; } if(minSize != INT_MAX) return S.substr(minbegin, minSize); else return ""; } };