Problem: Given a large string S and a smaller string T. Find the minimum size window in the string S which contains all the characters of the string T.
Solution:
- Maintain two pointers to store the begin and end positions of the window, two hash tables needToFind to store total count of a character in T and found to store total count of a character met so far and a count variable to store the total characters in T that's met so far. When count equals T's length, a valid window is found.
- Each time the end pointer is advanced, we increment hasFound[S[end]] by one. Increment count by one if hasFound[S[end]] is less than or equal to needToFind[S[end]]. If count equals to lengh of T then begin pointer can be advanced until found[S[begin]] is greater than needToFind[S[begin]].
- Finally we just need to set minWindowSize to currentWindowSize if currentWindowSize is less than currentWindowSize.
Implementation:
bool minWindow(std::string S, std::string T, int &minWindowBegin, int &minWindowEnd)
{
int lenS = S.size();
int lenT = T.size();
int needToFind[256] = {0};
int found[256] = {0};
for(int i = 0; i < lenT; ++i)
needToFind[T[i]]++;
int minWindowLen = INT_MAX;
int count = 0;
for(int begin = 0, end = 0; end < lenS; ++end)
{
if(needToFind[S[end]] == 0)
continue;
found[S[end]]++;
if(found[S[end]] <= needToFind[S[end]])
++count;
if(count == lenT)
{
while(needToFind[S[begin]] == 0 || found[S[begin]] > needToFind[S[begin]])
{
if(found[S[begin]] > needToFind[S[begin]])
--found[S[begin]];
++begin;
}
int currWindowLen = end - begin + 1;
if(currWindowLen < minWindowLen)
{
minWindowBegin = begin;
minWindowEnd = end;
minWindowLen = currWindowLen;
}
}
}
return count == lenT;
}
Complexity: O(n) where n is length of S.
No comments:
Post a Comment