今天做了头条笔试题,又是惨淡而归,一道不会,然后有人告诉我最后一道题是leetcode原题,看了之后,理解了普通的滑动窗口的解法,然后看了高赞的解答,感觉好精简的说,想了好久才想明白,这里解释一下高赞的解答。原题如下:
普通滑动窗口的Java代码如下(很容易理解,不解释):
public int longestOnes(int[] A, int K) {
int len = A.length, l = 0, num = 0, res = 0;
for(int r = 0; r < len; r++) {
if(A[r] == 0) {
num++;
}
while(num > K) {
if(A[l] == 0) {
num--;
}
l++;
}
res = Math.max(res, r - l + 1);
}
return res;
}
高赞解答的Java代码如下:
public int longestOnes(int[] A, int K) {
int i = 0, j;
for (j = 0; j < A.length; ++j) {
if (A[j] == 0) K--;
if (K < 0 && A[i++] == 0) K++;
}
return j - i;
}
看到这个代码,我的第一反应是这么简单?还可以这么写?然后就开始想为什么这么写,其实最重要的思想就是,窗口有两个变化趋势:第一个是,当K>=0时,长度增1,即j++,第二个是,当K<0时,长度不变,即j++,i++。i和j所确定的窗口不一定是最长的合法窗口,显然不可能所有的最长1区间都出现在尾部,但却一定和目前为止最长合法窗口的长度相等,因为它是从合法窗口移动过来的。最后为什么不是j-i+1呢?因为j会出界,而i不会,所以就不需要加1了。