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.
Analysis:
Use two map to store the expected char occured numbers(from T), realtime char occured numbers(From S)
Since we should implement this with O(n), we scan string S from the start to the end, use appeared varablile to recored how many chars have occued compared with T
If the (char is in T && its occued numbers < T), store it and its occued numbers in expectedMap, appeared++
If(appeared == T.lenth() )// substring could cover all chars in T
while(starting char is not in T || starting char numbers > expected number in T)
starting index++
if(win_len> current window length)
set new window
return ....
C++实现如下
string minWindow(string S, string T) {
if(S.size() == 0) return "";
if(T.size() > S.size()) return "";
int appearCount[256];
int expectCount[256];
memset(appearCount,0,256*sizeof(appearCount[0]));
memset(expectCount,0,256*sizeof(appearCount[0]));
for(int i=0; i<T.size();i++){
expectCount[T[i]]++;
}
int minV = INT_MAX, min_start=0;
int wid_start =0;
int appeared = 0;
for(int wid_end = 0; wid_end<S.size(); wid_end++){
if(expectCount[S[wid_end]] >0)
{
appearCount[S[wid_end]]++;
if(appearCount[S[wid_end]] <= expectCount[S[wid_end]])
appeared++;
}
if(appeared == T.size()){
while((appearCount[S[wid_start]]>expectCount[S[wid_start]]) || expectCount[S[wid_start]]==0)
{
appearCount[S[wid_start]]--;
wid_start++;
}
if(minV > (wid_end-wid_start+1))
{
minV = wid_end-wid_start+1;
min_start = wid_start;
}
}
}
if(minV == INT_MAX) return"";
return S.substr(min_start,minV);
}
Java实现如下
public String minWindow(String S, String T) {
int win_start = 0;
int win_realS = 0;
int win_len = Integer.MAX_VALUE;
int appeared = 0;
HashMap<Character, Integer> expected = new HashMap<Character, Integer>();
HashMap<Character, Integer> realAppeared = new HashMap<Character, Integer>();
for(int i=0;i<T.length();i++){//store T char into map
int val = 1;
if(expected.containsKey(T.charAt(i))){
val = expected.get(T.charAt(i));
val++;
}
expected.put(T.charAt(i), val);
}
for(int i=0;i<S.length();i++){
if(expected.containsKey(S.charAt(i))){
int val = 0;
if(realAppeared.containsKey(S.charAt(i))){
val = realAppeared.get(S.charAt(i));
val++;
}else{
val = 1;
}
realAppeared.put(S.charAt(i), val);
if(val<=expected.get(S.charAt(i)))
appeared++;
}
if(appeared == T.length()){//have all the chars
while(!expected.containsKey(S.charAt(win_start))
|| (expected.containsKey(S.charAt(win_start)) && realAppeared.get(S.charAt(win_start))>expected.get(S.charAt(win_start)))){
if(!expected.containsKey(S.charAt(win_start)))
win_start++;
else{
int val = realAppeared.get(S.charAt(win_start));
val--;
realAppeared.put(S.charAt(win_start), val);
win_start++;
}
}
if(win_len>i-win_start+1){
win_len = i-win_start+1;
win_realS = win_start;
}
}
}
return (win_len == Integer.MAX_VALUE) ? "" : S.substring(win_realS, win_realS+win_len);
}