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.
题目分析:得到字符串S中包含所有T的字母的最小子串,看到此题就想起了滑动窗口左右index处理,以及MAP处理保证所有的字符出现一次。
基本思路如下:
1. 采用MAP把T中的所有字符记录下来,这主要是为了处理重复字符
2. 采用begin,end两个变量记录字符串的开始和结束
3. 当map不够时,end前进一步,每发现一个,对应map值减一
4. 当map足够时,begin前进,每去掉一个,对应map值加一
具体代码如下:
public static String minWindow(String s, String t) {
String res = new String();
if (t == null || s == null)
return res;
if (t.length() <= 0 || s.length() <= 0)
return res;
Map<Character, Integer> map = new HashMap<Character, Integer>();
// 获取对应字符串map
for (int i = 0; i < t.length(); i++) {
char ch = t.charAt(i);
if (map.containsKey(ch)) {
map.put(ch, map.get(ch) + 1);
} else {
map.put(ch, 1);
}
}
int begin = 0;
int end = 0;
int minlen = Integer.MAX_VALUE;
int minbegin = -1;
int minend = -1;
//map不够,index++
while (end < s.length()) {
char ch2 = s.charAt(end);
if (map.containsKey(ch2)) {
map.put(ch2, map.get(ch2) - 1);
if (judge(map)) {
int winlen = end - begin + 1;
if (minlen > winlen) {
minlen = winlen;
minbegin = begin;
minend = end;
}
if(minlen==t.length()) break;
//map足够,begin++
while (begin <= end && judge(map)) {
if (judge(map)) {
int blen = end - begin + 1;
if (minlen > blen) {
minlen = blen;
minbegin = begin;
minend = end;
}
}
char ch3 = s.charAt(begin);
if (map.containsKey(ch3)) {
map.put(ch3, map.get(ch3) + 1);
}
begin++;
}
}
}
end++;
}
if (minend == -1)
return res;
else
return s.substring(minbegin, minend + 1);
}
public static boolean judge(Map<Character, Integer> map) {
for (Integer value : map.values()) {
if (value > 0)
return false;
}
return true;
}
@Test
public void case1() {
String s = "ADOBECODEBANC";
String t = "ABC";
String actual = minWindow(s, t);
String result = "BANC";
Assert.assertEquals(result, actual);
}
@Test
public void case2() {
String s = "BDAB";
String t = "AB";
String actual = minWindow(s, t);
String result = "AB";
Assert.assertEquals(result, actual);
}