This is suppose to be an easy question since I have already read through stormrage's post and thought I have mastered every detail about this code. But eventually it took me almost 3 hours straight to figure out a nice and clean code.
There are several things that one should notice in designing a robust algorithm for this problem:
- loop invariant: count <= total required chars. (excessive chars not accounted). If count < total required chars, we are building the first matching window. thus shrinking left edge is not necessary. Else if count == total required chars, Current window is either a half finished first time window or perfect left edge window with "one extra required char on the right edge " window. In both cases we can start shrinking left edge.
- We do not have to write a separate code block to do first time window matching because either the first matching or second matching requires left shrinking. Thinking of S = "aab" and T = "b".
So eventually with some modifications I come up with the following code. Alas, always think carefully before you start coding.
string minWindow(string S, string T) { if(S.size() < T.size() || !T.size()) return *(new string); vectorlmt(256); for(auto c:T) lmt[c]++; vector ct(256); int minLen = INT_MAX; string ret; int a0, a1, count; // left and right edge pointer. count = 0; for(a0 = 0, a1 = 0; a1 < S.size(); a1++) { // do right edge expand at loop start if(!lmt[S[a1]]) continue; // invalid char, keep expanding if(ct[S[a1]] < lmt[S[a1]]) count++; // char is needed now, increase count ct[S[a1]]++; // hasFound array+1 if(count == T.size()) { // loop invariant met, now do shrinking for(;a0 < a1; a0++) { // shrinking.... if(!lmt[S[a0]]) continue; // invalid char, keep shrinking ct[S[a0]] --; // good char, try hasFound-- // before shrinking if(ct[S[a0]] < lmt[S[a0]]) { // oops, should not delete this char. ct[S[a0]]++; // roll hasFound back. break; // don't move left edge pointer a0 } // it's ok to remove this char, keep // shrinking } if(a1 - a0 + 1 < minLen) { // one min window found. update minLen = a1-a0+1; ret = S.substr(a0, a1-a0+1); } } } if(minLen == INT_MAX) return *(new string); // INT_MAX is acting as safeguard. return ret; }
No comments:
Post a Comment