在使用滑动窗口之前,我们需要知道什么是滑动窗口,它又能帮助我们解决什么样的问题?
为了理解滑动窗口是什么,我们先来看一个简单的例子,难度指数:简单
这道题在leetcode上也能找到:209 Mininum Size Subarray Sum
( l < arr.length if(sum < s && r+1 < arr.lengthelseifmin(res, r-l+1if(res == arr.length+1) return 0; return res; } public static void main(String[] args) { int[] nums = {2, 3, 1, 2, 4, 3}; int s = 7; System.out.println(minSubArrayLen(s , nums)); }}
现在我们来看看下一个例子,难度:一般
可以看出,这道题和上一道思想上没有不同,都是创建一个滑动窗口来进行遍历,不过要注意的是这里使用的是一个freq[256]的整形数组来记录滑动窗口中字符的频率,而右边界r++,左边界l++的判断条件也不一样。可以总结出一个模板:
int l = 0, r = -1; while( l<s.length() ){ ifelse
创建一个滑动窗口,满足条件r++,否则l++;所以我们在这类大数组里找小数组的问题,都可以用这种模板,这时我们需要考虑的只是判断条件的不同。接下来,让我们看2个一样运用了滑动窗口的例子,这一次的例子比较难,我在这里先给出和两个题目,希望大家能独立完成,实在不行再来看下面的答案。
第一个问题的答案:
第二个问题的答案:
public class MininumWindowSubstring { public static String MininumWimow(String S, String T){ int[] freq = new int[256]; for( int i=0; i<T.length(); i++){ freq[T.charAt(i)]++; } String str = new String(); int l = 0, r = -1; int count = 0; int res = S.length()+1; while( l<S.length() ){ if( r+1<S.length() && count<T.length() ){ r++; if( freq[S.charAt(r)]>0) count++; freq[S.charAt(r)]--; }else{ if(freq[S.charAt(l)]>=0) count--; freq[S.charAt(l)]++; l++; } if( count == T.length() ){ if( r-l+1 < res ) str = S.substring(l , r+1); } } return str; } public static void main(String[] args) { String s = "ADOBECODEBANC"; String t = "ABC"; String str = MininumWimow( s, t); System.out.println(str); } }这里面的判断条件有不同的地方,但是模板还是一样的,都使用了freq[256]这个辅助数组,大家可以好好体会一下,不懂的可以在下面提问,看到了会回答的。
文章来源: 关于使用滑动窗口解决数组的一系列问题