76. Minimum Window Substring
by Botao Xiao
Question
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).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
Thinking:
- Method 1:双指针 TLE
class Solution {
public String minWindow(String s, String t) {
if(s == null || t == null) return "";
int min = Integer.MAX_VALUE;
String result = "";
int sLen = s.length();
int tLen = t.length();
char[] sArr = s.toCharArray();
char[] tArr = t.toCharArray();
Map<Character, Integer> cmp = new HashMap<>();
for(int i = 0; i < tLen; i++)
cmp.put(tArr[i], cmp.containsKey(tArr[i]) ? cmp.get(tArr[i]) + 1: 1);
for(int i = 0; i <= sLen - tLen; i++){
if(!cmp.containsKey(sArr[i])) continue;
Map<Character, Integer> temp = new HashMap<>();
temp.put(sArr[i], 1);
if(check(temp, cmp)){
result = s.substring(i, i + 1);
min = 1;
return result;
}
for(int j = i + 1; j < sLen; j++){
if(!cmp.containsKey(sArr[j])) continue;
temp.put(sArr[j], temp.containsKey(sArr[j])?temp.get(sArr[j]) + 1: 1);
if(check(temp, cmp)){
if(j - i + 1 < min){
min = j - i + 1;
result = s.substring(i, j + 1);
}
break;
}
}
}
return result;
}
private static boolean check(Map<Character, Integer> sMap, Map<Character, Integer> tMap){
Set<Character> set = tMap.keySet();
for(Character c : set){
if(!sMap.containsKey(c)) return false;
else
if(sMap.get(c) < tMap.get(c)) return false;
}
return true;
}
}
- Method 2: 滑动窗口
class Solution {
public String minWindow(String s, String t) {
if(s == null || t == null) return "";
int[] sMap = new int[256];
int[] tMap = new int[256];
int sLen = s.length();
int tLen = t.length();
for(int i = 0; i < tLen; i++)
tMap[t.charAt(i)]++;
int right = 0;
String result = "";
int min = Integer.MAX_VALUE;
for(int i = 0; i <= sLen - tLen; i++){
while(right < sLen && !check(sMap, tMap)){
sMap[s.charAt(right)]++;
right++;
}
if(check(sMap, tMap) && min > right - i + 1){
min = right - i + 1;
result = s.substring(i, right);
}
sMap[s.charAt(i)]--;
}
return result;
}
private boolean check(int[] sMap, int[] tMap){
for(int i = 0; i < sMap.length; i++){
if(tMap[i] > sMap[i])
return false;
}
return true;
}
}
二刷
这道题还是借鉴了一刷时候的结果,我先写出来了双指针的方法,最后一个test case无法通过。所以换成了滑动窗口的解法,最后AC。
class Solution {
public String minWindow(String s, String t) {
if(s == null || t == null) return "";
String result = "";
int res = s.length() + 1;
int[] tMap = new int[128];
char[] sArr = s.toCharArray();
char[] tArr = t.toCharArray();
for(int i = 0; i < tArr.length; i++)
tMap[tArr[i]]++;
int[] cmp = new int[128];
int right = 0;
for(int i = 0; i <= sArr.length - tArr.length; i++){
while(right < sArr.length && !same(tMap, cmp)){
cmp[sArr[right++]]++;
}
if(same(tMap, cmp) && right - i + 1 <= res){
res = right - i + 1;
result = s.substring(i, right);
}
cmp[sArr[i]]--;
}
return result;
}
private boolean same(int[] a, int[] b){
for(int i = 0; i < 128; i++)
if(a[i] != 0 && b[i] < a[i])
return false;
return true;
}
}
Subscribe via RSS