题目:
leetcode上的原题是:
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.
» Solve this problem
glassdoor上的题目概述为:
Given a stream of characters and a set of characters, find the shortest sequence in the stream containing all characters in the set.
分析:
两个题目说的是一个意思。首先,建立两个HashMap,把所有出现过的字符串放进去,初始值为0;在第二个HashMap把Set中的character的出现次数存放进去。
然后,遍历String,每次出现一个set中的character,存放到第一个Hashmap中,当所有set都出现过后,进入核心方法。
利用一个index(这里我们定义为start)遍历string,检查两个hashmap:如果第一个hashmap的start处大于第二个,那么第一个hashmap的当前value减少一位;如果两个hashmap在index处的value相同,且不为0,那么,检查start到第一个遍历string指针处这段字符串,长度如果短于之前的字符串,那么更新结果,否则继续循环,直到便利完成。
代码:
//Array法
public class Solution {
public String minWindow(String S, String T) {
// Start typing your Java solution below
// DO NOT write main() function
int[] needFind = new int[256];
int[] hasFind = new int[256];
int cnt = 0, len = Integer.MAX_VALUE, start = 0;
String res = "";
for(char c : T.toCharArray()) needFind[c]++;
for(int i=0; i<S.length(); i++){
char c = S.charAt(i);
if(needFind[c] == 0) continue;
hasFind[c]++;
if(hasFind[c] <= needFind[c]) cnt++;
if(cnt == T.length()){
while(hasFind[S.charAt(start)]==0 || hasFind[S.charAt(start)]>needFind[S.charAt(start)]){
if(hasFind[S.charAt(start)]>needFind[S.charAt(start)]) hasFind[S.charAt(start)]--;
start++;
}
if(i-start+1 < len){
res = S.substring(start, i+1);
len = i-start+1;
}
}
}
return res;
}
}
//HashMap法
public class Solution {
public String minWindow(String S, String T) {
// Start typing your Java solution below
// DO NOT write main() function
HashMap<Character, Integer> needFind = new HashMap<Character, Integer>();
HashMap<Character, Integer> hasFind = new HashMap<Character, Integer>();
String total = "" + S + T, res = "";
int cnt = 0, start = 0, len = Integer.MAX_VALUE;
for(char c : total.toCharArray()){
needFind.put(c, 0);
hasFind.put(c, 0);
}
for(char c : T.toCharArray()) needFind.put(c, needFind.get(c)+1);
for(int i=0; i<S.length(); i++){
char c = S.charAt(i);
if(!needFind.containsKey(c)) continue;
hasFind.put(c, hasFind.get(c)+1);
if(hasFind.get(c) <= needFind.get(c)) cnt++;
if(cnt == T.length()){
while(hasFind.get(S.charAt(start))==0 || hasFind.get(S.charAt(start))>needFind.get(S.charAt(start))){
if(hasFind.get(S.charAt(start))>needFind.get(S.charAt(start))) hasFind.put(S.charAt(start), hasFind.get(S.charAt(start))-1);
start++;
}
if(i-start+1 < len){
res = S.substring(start, i+1);
len = i-start+1;
}
}
}
return res;
}
}
总结:
简单来说,思路就是利用两个Hashmap的Two Pointers方法,很经典。