题目描述:
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 empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
我的思路是这样的:
假设s=“DCABBABAAC”.t="AABC"
1、先用hashMap在s中找到第一个能包含t的子串,那就是CABBA(如果找不到就返回""),并且记下第一个匹配t的字母及其位置。startChar='C',startIndex=1,以及匹配的最后一个字母的位置lastIndex=5.
2、然后,从lastIndex后面的字母开始找,如果和startChar相等,就从后往前查找能够覆盖t的子串。对于这个例子来讲就是当lastIndex走到C时,C==startChar,,就从C从后往前到BAAC符合题意。
但是这样的时间复杂度是O(m*n)。超时了- -!
代码如下:
public class Solution {
public String minWindow(String s, String t) {
Map
map=new HashMap
();
for(int i=0;i
0&&lastIndex
0){
if(map.containsKey(s.charAt(startIndex))){
if(map.get(s.charAt(startIndex))==1)
map.remove(s.charAt(startIndex));
else
map.put(s.charAt(startIndex), map.get(s.charAt(startIndex))-1);
}
startIndex--;
}
startIndex++;
startChar=s.charAt(startIndex);
result=s.substring(startIndex, lastIndex+1);
}
lastIndex++;
}
return result;
}
}
后来实在是想不到,看了别人的做法,时间复杂度是O(n)。
用dict来记录t中每个字母的个数,用found来记录已经发现的字母的个数,然后每次移动start的值,直到start和end正好可以包括t。
代码如下:
public String minWindow(String S, String T) {
HashMap
dict = new HashMap<>();
for (int i = 0; i < T.length(); i++) {
char c = T.charAt(i);
if (!dict.containsKey(c))
dict.put(c, 1);
else
dict.put(c, dict.get(c) + 1);
}
HashMap
found = new HashMap<>();
int foundCounter = 0;
int start = 0;
int end = 0;
int min = Integer.MAX_VALUE;
String minWindow = "";
while (end < S.length()) {
char c = S.charAt(end);
if (dict.containsKey(c)) {
if (found.containsKey(c)) {
if (found.get(c) < dict.get(c))
foundCounter++;
found.put(c, found.get(c) + 1);
} else {
found.put(c, 1);
foundCounter++;
}
}
if (foundCounter == T.length()) {
//When foundCounter equals to T.length(), in other words, found all characters.
char sc = S.charAt(start);
while (!found.containsKey(sc) || found.get(sc) > dict.get(sc)) {
if (found.containsKey(sc) && found.get(sc) > dict.get(sc))
found.put(sc, found.get(sc) - 1);
start++;
sc = S.charAt(start);
}
if (end - start + 1 < min) {
minWindow = S.substring(start, end + 1);
min = end - start + 1;
}
}
end++;
}
return minWindow;
}