LeetCode 1004. 最大连续1的个数 III

https://leetcode-cn.com/problems/max-consecutive-ones-iii/

这个题一看就是滑动窗口的题,但是滑动窗口也有不同的优化方法。

class Solution {
    public int longestOnes(int[] A, int K) {
        if (A.length == 0) {
            return 0;
        }
        int fast = 0;
        int slow = 0;
        int max = 0;
        int cur = 0;
        int count = K;
        while (fast < A.length) {
            if (A[fast] == 1) {
                cur++;
            } else if (A[fast] == 0) {
                if(count > 0){
                    cur++;
                    count--;
                }else {
                    while (slow < fast && count <= 0) {
                        if (A[slow] == 0) {
                            count++;
                        }
                        slow++;
                        cur--;
                    }
                    if(count > 0) {
                        count--;
                        cur++;
                    }
                }
            }
            max = Math.max(max, cur);
            fast++;
        }
        return max;
    }
}

上面就是我第一次提交的答案,可以看到做的还是很乱的,有很多地方可以优化。具体的思路就是快指针去遍历,遇到0的时候就分两种情况,第一种就是目前可以将0替换成1,那我们直接替换,将K的大小减一。如果没有可以替换的情况,我们就移动慢指针到K大于0.

我这种代码写的还是非常混乱的,特别是在移动慢指针的情况下有很多优化的地方。

    public int longestOnes(int[] A, int K) {
        if (A.length == 0) {
            return 0;
        }
        int fast = 0;
        int slow = 0;
        int max = 0;
        while (fast < A.length) {
            if(A[fast] == 0){
                if(K > 0){
                    K--;
                }else{
                    max = Math.max(max,fast - slow);
                    //这个是个巧妙地地方,A[slow++]==1,我们会访问到当前滑动窗口中第二次出现为0的地方,因为我们判断A[slow] == 1之后,仍然会执行一次slow++
                    while(A[slow++] == 1);
                }
            }
            fast++;
        }
        return Math.max(max,fast-slow);
    }

第二次写的代码,也是参考了评论区的,我们根本没必要去管等于1的情况,直接右移即可。当我们遇到0并且K小于等于0的情况,这个代码就很巧妙的解决了这个问题。直接寻找当前窗口中第二个0的位置。

原文地址:https://www.cnblogs.com/ZJPaang/p/13020218.html