题目: Minimum Window Substring
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.
补充:
如果T="ABCC",那么上题的解即为"ADOBEC"了。
故此题要求得到S中的包含T中所有字符且相应字符的出现次数也相等的最小子串。
分析:这道题的难点是,给出任意i, j,如何在O(1)时间内判断S[i..j]符合上述条件。
首先,我们可以想到构造哈希表tmap,对于T中的每个字符c均有tmap[c] = (字符c在T中出现的次数)
。
int[] tmap = new int[256];
for (int i = 0; i < T.length(); i++) {
tmap[T.charAt(i)]++;
}
接下来,为S的子串构造一个哈希表smap,同样的,对于S子串中的每一个字符c均有smap[c] = (字符c在S子串中出现的次数)
。
建立两个指针, left和right,如果S[left..right)不符合条件,那么right++。那么如何O(1)时间判断子串是否符合条件呢?答案是采用一个计数器count,对于每次取到一个字符,判断smap[c]是否小于tmap[c], 如果成立,则count++。否则,不累加。
当count == T.length()
时,则表明当前S[left..right)
符合条件,归档存下,继续往下查找。
代码:
public class Solution {
public String minWindow(String S, String T) {
// 1. build the hashmap
int[] tmap = new int[256];
int[] smap = new int[256];
int t_count = T.length();
for (int i = 0; i < T.length(); i++) {
tmap[T.charAt(i)]++;
}
int slen = S.length();
int left = 0, right = 0;
int ml = 0, mr = 0, min = Integer.MAX_VALUE;
int count = 0;
boolean found = false;
while (right < slen) {
// 1. right++ until find the a window
char c;
while (right < slen && count < t_count) {
c = S.charAt(right);
if (smap[c] < tmap[c]) count++;
smap[c]++;
right++;
}
if (count != t_count) {
break;
}
// 2. left++ until broke the window
while (left < right && count == t_count) {
c = S.charAt(left);
smap[c]--;
if (smap[c] < tmap[c]) {
count--;
break;
}
left++;
}
// 3. window is [left, right)
if (right - left < min) {
min = right - left;
ml = left;
mr = right;
found = true;
}
left++;
}
if (found == false) return "";
return S.substring(ml, mr);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。