题目描述:
思路(滑动窗口):因为题目只是由英文字母组成,所以可以用一个 一维数组来存储s和t中的元素。
- 把字符串 t 的每个字符存入数组,值表示该字母在整个字符串中出现的次数;
- 遍历字符串s,用滑动窗口的思想,保持窗口左侧不动,只将窗口右侧向右移动,移动窗口的同时在数组中减去窗口内出现相应字母的次数,使用一个变量contains来记录匹配的字母个数,如果遍历到某一窗口时,contains的值等于字符串t 的长度,则表示窗口内已经包含了所有匹配的字符;
- 这是开始将窗口左侧向右移动,同时更新子串的最短长度。
class Solution {
public String minWindow(String s, String t) {
int len1 = s.length();
int len2 = t.length();
if(len2 > len1) return "";
int[] count = new int[52];
Arrays.fill(count, Integer.MIN_VALUE);
int contains = 0;
//字符串 t 的每个字符存入数组
for(int i=0;i<len2;i++){
char c = t.charAt(i);
if(count[getIndex(c)] == Integer.MIN_VALUE){
count[getIndex(c)] = 1;
}
else{
count[getIndex(c)]++;
}
}
int left = 0, right = len1 - 1;
//遍历字符串s,滑动窗口
for(int i=0,j=0;j<len1;j++){
char c = s.charAt(j);
//匹配t中的字符,用contains计数
if(count[getIndex(c)] != Integer.MIN_VALUE){
if(count[getIndex(c)] > 0){
contains++;
}
count[getIndex(c)]--;
}
//字符串s的左边进行滑动
char tail = s.charAt(i);
//删除t中没有的字符和s中字符数大于t的字符数的字符
while(i < j && (count[getIndex(tail)]==Integer.MIN_VALUE||count[getIndex(tail)]<0)){
count[getIndex(tail)]++;
i++;
tail = s.charAt(i);
}
// 更新
if(contains == len2 && j - i < right - left){
right = j;
left = i;
}
}
//对于最后一次的更新
if(contains == len2){
return s.substring(left, right + 1);
}else{
return "";
}
}
public int getIndex(char c){
// 小写字母
if(c >= 97){
return c - 97;
}else if(c >= 65){
return c - 39;
}
return -1;
}
}