public class Solution {
/**
*
* @param S string字符串
* @param T string字符串
* @return string字符串
*/
public String minWindow (String S, String T) {
/*
1) left开始指向0, right一直后移,直到right - left区间包含T中所有字符。
记录窗口长度minLen
2) 然后left开始后移移除元素,直到移除的字符是T中的字符则停止,此时T中有一个字符没被
包含在窗口,
3) 继续后移right,直到T中的所有字符被包含在窗口,重新记录最小的窗口minLen。
4) 如此循环直到right到S中的最后一个字符。
时间复杂度为O(n)
*/
// write code here
//由于S和T中均只包含大小写字母,所以可以用一个大小为128的数组存储其字符出现次数,数组下标对应字符值
int[] map = new int[128];//A-Z==65-91 a-z==97-123
for (int i = 0; i < T.length(); i++) {
map[T.charAt(i)]++;
}
//start记录当前最小滑动窗口的开始位置。left和right为当前滑动窗口的左右指针,
// 当满足left和right对应的滑动窗口包含T的所有字符,且该滑动窗口的大小小于minLen时,更新当前滑动窗口大小,及其开始位置
int start = 0, left = 0, right = 0,count = T.length(),minLen = Integer.MAX_VALUE;
while (right<S.length()){
if(map[S.charAt(right)] >0){//先判断,再减去1,若该值不存在,则会被更新为-1,若该值存在被更新为0
count--;
map[S.charAt(right)]--;
right++;
}else{
map[S.charAt(right)]--;
right++;
}
while (count == 0){
if(right-left < minLen){
start = left;
minLen = right-left;
}
if(map[S.charAt(left)] == 0){
count++;
map[S.charAt(left)]++;
left++;
}else {
map[S.charAt(left)]++;
left++;
}
}
}
return minLen==Integer.MAX_VALUE?"":S.substring(start,start+minLen);
}
}