LeetCode One question per day -2.15-485. The maximum number of consecutive 1s + 2.19-1004. The maximum number of consecutive 1s III

Paper full of absurd warnings!


485

Title description

Insert picture description here

Idea sliding window

This question actually does not require sliding windows. If you encounter 1, cnt++, you can reset to 0 when you encounter 0cnt, but a dedicated job hunter must practice sliding windows.

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 1) {
    
    
                r++;
            } else {
    
    
                //r一定会会先遇到0,l会停在第一个1
                //这时候r-l就是1的长度
                ans = max(ans, r - l);
                r++;
                l = r;
            }
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        ans = max(ans, r - l);
        return ans;
    }
};

The idea of ​​the above code sliding:
if you encounter a 1, r++, expand the window without performing other operations; this leads to if it is 1 at the end, you must calculate it again.
If you encounter a 0, calculate the result, because here It is delayed, r = 0, indicating that the [L, R) interval is a correct interval, and then R++, L = R, cross this 0. In general, when you encounter RL, you have to calculate it once more.
Time O(n)
Space O(1) When
doing this problem, I think it’s quite natural, but when I do the next problem, I feel strange.

1004

Title description

Insert picture description here

Idea sliding window

For this question, you can't directly judge 0 with a single pointer and then clear it, because each 0 may be a starting point.
Then still use a sliding window,

class Solution {
    
    
public:
    int longestOnes(vector<int>& A, int K) {
    
    
        int len = A.size();
        if(K == len) return len;
        int left = 0, right = 0;
        int ans = 0;
        int zeroSum = 0;
        while(right < len) {
    
    
            if(A[right] == 0) {
    
    
                zeroSum++;
            }
            while(zeroSum > K) {
    
    
                if(A[left] == 0) {
    
    
                    zeroSum--;
                }
                left++;
            }
            ans = max(ans, right - left + 1);
            right++;
        }
        return ans;
    }
};

The idea is also obvious. When you
encounter a 0, first change "it becomes 1". If the number of times is enough, it will be fine;
but if you find that it is used more, you need to keep shrinking the left boundary until a 0 is discarded,
and then calculate the interval size every time.

Hey, thinking about it this way will make you feel weird. Why do you need to count one more time at the end of the first question? Is the idea not good enough? Can you use the insect movement method like the second question?
ps: Insect movement method The
right boundary keeps squirming, and the left boundary keeps squirming when it is found in a special period. It is correct every time it stops.
So began to process the code of the first question.
This is the first version

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 0)
            {
    
    
                l = r;
                while(nums[r] == 0) {
    
    
                    l++;
                    r++;
                }
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        return ans;
    }
};

The idea is to ignore when encountering 1, expand the window. When
encountering 0, look for an interval that does not start at 0,
and then calculate the window size each time

It was strange to see, but as expected, the
case [0] crossed the boundary, because the r in the while crossed the boundary,
and then changed it again.

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 0)
            {
    
    
                l = r;
                while(r < len && nums[r] == 0) {
    
    
                    l++;
                    r++;
                }
            } else {
    
    
                ans = max(ans, r - l + 1);
                r++;
            }
        }
        return ans;
    }
};

Increased condition, which the while determining the boundary r is not
just this is not enough, if the case of [0], the first ans will equal 1, is wrong
so the following code in the else get into, i.e. only the nums [r] It is equal to 1 to calculate the window size.
This is correct.
However, in the code of 1004, [0] does not appear, and 0 will be wrong. The reason is that its L will become 1, and the calculation result is, 0-1 + 1 = 0.
Obviously, K=0 of 1004 is 485, so we change the code again

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        int zeroSum= 0;
        while(r < len) {
    
    
            if(nums[r] == 0) {
    
    
                zeroSum++;
            }
            while(zeroSum > 0) {
    
    
                if(nums[l] == 0) {
    
    
                    zeroSum--;
                }
                l++;
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        return ans;
    }
};

Simplification

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        int zeroSum= 0;
        while(r < len) {
    
    
            if(nums[r] == 0) {
    
    
                while(nums[l] != 0) {
    
    
                    l++;
                }
                l++;
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        return ans;
    }
};

I changed it for a long time... I also went to play Hollow Knight in the middle of autism. Of course I found Hollow Knight was more autistic, and then came back.
The difficulty is that L++ must be used at the end of the while loop; that is, a 0 must be crossed (no matter what k is), so the result must be correct.
Give a few examples

K = 0
1 1 0  
出循环时 L = 3 R = 2

K = 1
1 1 0 0 
出循环时 L = 4 R = 4

It's just an article written for yourself to see. Just look at it and guess what 233333
said so much. The main thing is to express the seemingly the same topic by analogy, but don't think about it, sometimes it will be a mess if you don't pay attention. .

Guess you like

Origin blog.csdn.net/qq_42883222/article/details/113886972