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.
思路:
1. 维护一个map<Character, Integer>来表示每个字母还可以出现的次数。开始的时候建立map,字母对应在target string里出现的次数。另外一个count
2. 对长sring扫描,如果遇到map里存在的字母,就对对应的值-1 (注意这里可以是负数,表示该位字母出现多次,但是我们不计算在总count里).如果该值>=0则总count++,表示总共找到的字母增加一位。
3. 如果count = target.length()说明已经全部找到,这时窗口左边向右移动,如果对应的值在map里,那就把map里的value+1,因为我们需要寻找的字母又少了一个。在value+1后,如果count<target.length(),说明我们又可以开始寻找下一个了,就先计算一下当前match的长度:right-left+1
public String minWindow(String S, String T) {
if (T.length() == 0) {
return "";
}
int count = 0;
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < T.length(); i++) {
char c = T.charAt(i);
if (map.get(c) == null) {
map.put(c, 1);
} else {
map.put(c, map.get(c)+1);
}
}
int minLen = Integer.MAX_VALUE;
String result = "";
int left = 0, right = 0;
while (left <= S.length() - T.length() && right < S.length()) {
if (map.containsKey(S.charAt(right))) {
map.put(S.charAt(right), map.get(S.charAt(right))-1);
if (map.get(S.charAt(right)) >= 0) {
count++;
}
while (count == T.length()) {
if (map.get(S.charAt(left)) != null) {
map.put(S.charAt(left), map.get(S.charAt(left))+1);
if (map.get(S.charAt(left)) > 0) {
int curLen = right-left+1;
if (curLen < minLen) {
minLen = Math.min(minLen, curLen);
result = S.substring(left, right+1);
}
count--;
}
}
left++;
}
}
right++;
}
return result;
}