滑动窗口
经典写法
java
class Solution {
public String minWindow(String s, String t) {
HashMap<Character, Integer> window = new HashMap<>(), need = new HashMap<>();
for(char c : t.toCharArray()) need.merge(c, 1, Integer::sum);
int cnt = 0, start = 0, len = Integer.MAX_VALUE;
for(int l = 0, r = 0; r < s.length(); r++){
// 窗口增大的逻辑
char c = s.charAt(r);
if(need.containsKey(c)){
window.merge(c, 1, Integer::sum);
if(need.get(c).equals(window.get(c))) cnt++;
}
while(cnt == need.size()){ // 窗口何时缩小
// 更新答案
if(len > r - l + 1){
len = r - l + 1;
start = l;
}
// 窗口缩小的逻辑
c = s.charAt(l++);
if(need.containsKey(c)){
if(need.get(c).equals(window.get(c))) cnt--;
window.merge(c, -1, Integer::sum);
}
}
}
return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
}
}
简洁写法
java
class Solution {
public String minWindow(String s, String t) {
char[] chs = s.toCharArray(), cht = t.toCharArray();
int[] hash = new int[128];
for(char c : cht) hash[c]--;
int cnt = 0, m = cht.length;
String res = "";
for(int l = 0, r = 0; r < chs.length; r++){
hash[chs[r]]++;
if(hash[chs[r]] <= 0) cnt++;
while(cnt == m && hash[chs[l]] > 0) hash[chs[l++]]--;
if(cnt == m){
if(res.equals("") || res.length() > r - l + 1){
res = s.substring(l, r + 1);
}
}
}
return res;
}
}
一个坑
两个 Integer 相等比较应该用 equals,而不是 ==。
一个 Integer 和一个 int 比较,Integer 会自动拆箱,可以用 ==。
java
class Solution {
public String minWindow(String s, String t) {
int i = 0;
HashMap<Character, Integer> mapS = new HashMap<>();
HashMap<Character, Integer> mapT = new HashMap<>();
for(char c : t.toCharArray()){
//mapT.merge(c, 1, Integer::sum);
mapT.put(c, mapT.getOrDefault(c, 0) + 1);
}
int cnt = 0;
int res = Integer.MAX_VALUE, left = 0, right = 0;
for(int j = 0; j < s.length(); j++){
char c = s.charAt(j);
if(mapT.containsKey(c)){
//mapS.merge(c, 1, Integer::sum);
mapS.put(c, mapS.getOrDefault(c, 0) + 1);
if(mapS.get(c).equals(mapT.get(c))){ // 一个坑:Integer 相等比较应该用 equals,而不是 ==
cnt++;
}
}
while(cnt == mapT.size()){
if(res > j - i + 1){
left = i;
right = j;
res = j - i + 1;
}
c = s.charAt(i++);
if(mapT.containsKey(c)){
//mapS.merge(c, -1, Integer::sum);
mapS.put(c, mapS.getOrDefault(c, 0) - 1);
if(mapS.get(c).compareTo(mapT.get(c)) < 0){
cnt--;
}
}
}
}
return res == Integer.MAX_VALUE ? "" : s.substring(left, right + 1);
}
}