目录
- 思路
- 代码
思路
滑动窗口,记录区间【left,right】之间的子串覆盖没覆盖t,就是t里面的元素是不是在区间之内都找到。
有几个比较难的问题
- 怎么确定满足条件了,就是【left,right】之间的子串已经覆盖t,
我们可以将t用map存,这个map不会太大,因为就是大小写字母,key是字符,v是出现的次数。
然后遍历s,如果s的第i个字符在之前的map里面,则减1,当减到为0,则这个字符满足条件,然后如果t里面所有的字符都满足条件,则可以计算结果,长度为right-left+1;
之后就是左边界往右走,往右走是map里面的值加一,如果加大某一个字符的map值大于0了,则不满足条件了,right再加。
代码
class Solution {
public String minWindow(String s, String t) {
Map<Character, Integer> map = new HashMap<>(80);
int totalT =0;
for (int i = 0; i < t.length(); i++) {
if (map.containsKey(t.charAt(i))){
int cnt = map.get(t.charAt(i));
map.put(t.charAt(i), cnt+1);
}else {
totalT++;
map.put(t.charAt(i),1);
}
}
int left = 0;
int right = 0;
int result =Integer.MAX_VALUE;
String resultString = "";
for (right = 0; right < s.length(); right++){
if (map.containsKey(s.charAt(right))){
int k = map.get(s.charAt(right));
map.put(s.charAt(right),k-1);//可以继续减,减成负值
if (k-1 == 0){//正好满足条件
totalT--;
if (totalT == 0){
while (left<=right){
if (map.containsKey(s.charAt(left))){
int p = map.get(s.charAt(left));
if(p == 0){//减去这个就不行了
if (result > (right -left +1)){ //先记录答案
result = right-left+1;
resultString = s.substring(left,right+1);
}
totalT++;//重新计算答案
map.put(s.charAt(left),p+1);
left++;
break;
}
map.put(s.charAt(left),p+1);
}
left++;
}
}
}
}
}
//
return resultString;
}
}