给了字符串s和t,输出包含所有t中字符(注意是所有,1个字母有两次要输出两次)的最小长度的s的子串
如果要求最长,则while一直加end加到不符合条件,开始增加start直到符合条件,之后再开始增加end直到最后。
如果要求最短,则while一直循环加end到符合条件,开始增加start直到不符合条件,之后再开始增加end直到最后。
如果要符合某个条件有三种情况时,不要把增加写到第一步,因为不确定如果此时符合一种条件时该不该加,两种情况的话好说因为不是你就是我,但是三种有可能有的不能加。
然后初始的left和right都可以是0,然后while的循环条件为right<s.size()
进入循环后首先保存此时要添加的值,右移窗口,然后进行窗口数据更新,接着用一个while循环判断左侧窗口是否要收缩,如果要收缩,则首先保存此时要删掉的数据,然后start右移,接着进行窗口数据更新
这是一个左闭右开窗口。
class Solution {
HashMap<Character,Integer> map1=new HashMap<>();//t中的所有字符次数的map
HashMap<Character,Integer> map2=new HashMap<>();//窗口中所有字符次数的map
public String minWindow(String s, String t) {
int sl=s.length();
int tl=t.length();
char[] S=s.toCharArray();
char[] T=t.toCharArray();
for(int i=0;i<tl;i++){
map1.put(T[i],map1.getOrDefault(T[i],0)+1);
}
int start=0;
int end=0;
int min=Integer.MAX_VALUE;
int res1=-1,res2=-1;
while(end<sl){
char c=S[end];
end++;
if(map1.containsKey(c)){
map2.put(c,map2.getOrDefault(c,0)+1);
}
while(check()){
if(end-start<min){
min=end-start;
res1=start;
res2=end;
}
char d=S[start];
start++;
if(map1.containsKey(d)){
map2.put(d,map2.getOrDefault(d,0)-1);
}
}
}
return res1==-1?"":s.substring(res1,res2);
}
public boolean check() {//遍历所有的字符串t,看现在窗口中是否包含。
Iterator iter = map1.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (map2.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
}
}