题目链接:
题目描述:
思路:
用滑动窗口,
- 固定左边,扩大右边,直到窗口里有全部的t
- 缩小左边,保证窗口里有t,找到最短的子串
- 怎么查看是否有全部的t?
把t的字母放到map里,key是字母,value是个数,统计map的大小count(就是一共有多少种有字母);遍历s的字母,看是否在map里,是的话就把个数-1,如果某个字母的个数减为0,说明这个字母在s和t里面已经相等了,count-1,直到count为0 ,此时说明窗口内的包含t里面所有字母
-怎么在缩小左边的同时保证窗口内有t
当count为0,不断缩小左边,遍历左边的每一个字母,如果在map里面,value++,如果value>0,说明窗口里面少了t中某个字母,这时候就要继续移动右边
缩小左边就是左指针右移
实现代码:
class Solution {
public String minWindow(String s, String t) {
int slen = s.length(), tlen = t.length();
if(tlen ==0 || slen==0 || tlen > slen){
return "";
}
Map<Character, Integer> map = new HashMap<>();
//放入map
for(char c : t.toCharArray()){
map.put(c,map.getOrDefault(c,0) + 1);
}
int count = map.size();
int left = 0, right = 0, len = Integer.MAX_VALUE, minleft = -1;
while(right < slen){
//查看是否包含t中字母
char c = s.charAt(right);
if(map.containsKey(c)){
map.put(c,map.get(c) - 1);//消除
if(map.get(c) == 0){
count--;
}
}
right++;
//已经包含t,需要缩小窗口
while(count == 0){
if(right-left < len){
len = right-left;
minleft = left;
}
//查看是否把关键字母移出去了
char cl = s.charAt(left);
if(map.containsKey(cl)){
map.put(cl,map.get(cl) + 1);
if(map.get(cl) > 0){
count++;
}
}
left++;
}
}
return len == Integer.MAX_VALUE ? "" : s.substring(minleft,len+minleft);
}
}