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.
Hash Table Two Pointers String
Solution in Java:
public class Solution {
public String minWindow(String S, String T) {
if(S==""||T==""||S.length()<T.length()) return "";
//map is a hashmap for recording the times of characters in T appear,
//and how namy times the corresponding characters appear in the window of S
Map<Character, Integer> map = new HashMap<Character, Integer>();
//build the hashmap for characters in T
for(int m=0; m<T.length(); m++){
char cur = T.charAt(m);
if(map.containsKey(cur)){
int dup = map.get(cur);
map.put(cur, ++dup);
}
else
map.put(cur, 1);
}
//need is the total number of characters in T
int need = T.length();
//find the first window in S contains T
int minstart=0, minend = S.length()-1;
for(int n=0; n<S.length();n++){
if(need==0){ //need =0 means the current window contains T
minend = n-1;
break;
}
char cur = S.charAt(n);
if(map.containsKey(cur)){
int dup = map.get(cur);
if(dup>0){ //dup >0 means to cover all characters in T,
need--; //still needing this character cur, so after adding cur, need-1;
}
map.put(cur, --dup);
}
}
if(need>0) return "";//characters in S cannot cover characters in T
//shrink for the first minstart, minend
while(!map.containsKey(S.charAt(minstart)) || map.get(S.charAt(minstart))<0){
//if map contains S.charAt(minstart) and map.get(S.charAt(minstart)) < 0, that means
//now the window in S contains more S.charAt(minstart) than it needs (the number of this //characters appear in T), we then shrink the window
if(map.containsKey(S.charAt(minstart))){
int dup = map.get(S.charAt(minstart));
map.put(S.charAt(minstart), ++dup);
}
minstart++;
}
int curstart = minstart, curend = minend;
//on the base of curstart, curend, each time shift the window to the right by one position,
//and check if the need is 0. If it is, we find another window that can cover T, and begin to
//shrink the window
while(curend<S.length()-1){
char sChar = S.charAt(curstart);
//check if the first character that will be removed from the window is needed to cover T
if(map.containsKey(sChar)){
int dup = map.get(sChar);
if(dup>=0){ //only when dup>=0, this character is needed to cover T,
need++; //so after removing this character, we need one more character to //cover T, need++
}
map.put(sChar, dup+1); //remove sChar from the window, and modify the map
}
curstart = curstart + 1;
curend = curend + 1;
char eChar = S.charAt(curend);
//check if the last character that will be added to the window is needed to cover T
if(map.containsKey(eChar)){
int dup = map.get(eChar);
if(dup>0){ //only when dup>0, this character is needed to cover T
need--; //so after adding this character, we need one less character to cover T
//so we have need--
}
map.put(eChar, --dup);
}
if(need==0){ //begin to shrink
while(!map.containsKey(S.charAt(curstart)) || map.get(S.charAt(curstart))<0){
if(map.containsKey(S.charAt(curstart))){
int dup = map.get(S.charAt(curstart));
map.put(S.charAt(curstart), ++dup);
}
curstart++;
}
minstart = curstart;
minend = curend;
}
}
return S.substring(minstart, minend+1);
}
}
Note:
1. 注意a++和++a的区别,a++第一遍先返回a再执行++(居然被这个坑了。。)
2. 首先找出S中包含T的第一个窗口(如果存在),然后以此窗口位基础,以这个宽度不断向右平移,如果新窗口能够包含T,再试图缩小窗口,获得更小的窗口
3. hashmap map中,以相应字符为key值,而相对应的value表示该字符在现在的window中是刚好(value=0), 是缺乏(value>0),还是富余(value<0)

5万+

被折叠的 条评论
为什么被折叠?



