labuladong算法小抄里面滑动窗口C++解法的java版。
1.把[left,right]称为一个窗口;
2.先右移右指针扩大窗口,直到窗口中的数字满足small数组要求;
3.满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求
4.重复2,3步直到right走到big尽头
Talk is cheap, show me the code.
class Solution {
public int[] shortestSeq(int[] big, int[] small) {
//左右双指针表示滑动窗口,start和min用来保存最优解
int left = 0,right = 0,start = 0;
int min = Integer.MAX_VALUE;
//window用来记录当前窗口包含的字符和出现的次数
//needs用来记录small当中出现的字符和包含的次数
HashMap window = new HashMap();
HashMap needs = new HashMap();
//记录small中出现的字符和包含的次数
for(Integer c:small ) needs.put(c,needs.getOrDefault(c,0)+1);
//match用来保存匹配的个数
int match = 0;
//移动right扩大窗口
while(right<big.length){
Integer c1 = big[right];
if(needs.containsKey(c1)){
window.put(c1,window.getOrDefault(c1,0)+1);
if(window.get(c1)==needs.get(c1)){
match++;
}
}
right++;
//当匹配个数满足small时,移动 left 缩小窗口进行优化
while (match==needs.size()){
//更新最小窗口
if(right-left<min){
start = left;
min = right-left;
}
Integer c2 = big[left];
if(needs.containsKey(c2)){
window.put(c2,window.getOrDefault(c2,0)-1);
if(window.get(c2)<needs.get(c2)){
match--;
}
}
left++;
}
}
return min == Integer.MAX_VALUE? new int[0]:new int[]{start,min+start-1};
}
}