Given a binary array, find the maximum number of consecutive 1s in this array if you can flip at most one 0.
Example 1:
Input: [1,0,1,1,0] Output: 4 Explanation: Flip the first zero will get the the maximum number of consecutive 1s. After flipping, the maximum number of consecutive 1s is 4.
Note:
- The input array will only contain
0
and1
. - The length of input array is a positive integer and will not exceed 10,000
Follow up:
What if the input numbers come in one by one as an infinite stream? In other words, you can't store all numbers coming from the stream as it's too large to hold in memory. Could you solve it efficiently?
這道題在之前那道題Max Consecutive Ones的基礎上加了一個條件,說我們有一次將0翻轉成1的機會,問此時最大連續1的個數,再看看follow up中的說明,很明顯是讓我們只遍歷一次數組,那我們想,肯定需要用一個變量cnt來記錄連續1的個數吧,那么當遇到了0的時候怎么處理呢,因為我們有一次0變1的機會,所以我們遇到0了還是要累加cnt,然后我們此時需要用另外一個變量cur來保存當前cnt的值,然后cnt重置為0,以便於讓cnt一直用來統計純連續1的個數,然后我們每次都用用cnt+cur來更新結果res,參見代碼如下:
解法一:
class Solution { public: int findMaxConsecutiveOnes(vector<int>& nums) { int res = 0, cur = 0, cnt = 0; for (int num : nums) { ++cnt; if (num == 0) { cur = cnt; cnt = 0; } res = max(res, cnt + cur); } return res; } };
上面的方法有局限性,如果題目中說能翻轉k次怎么辦呢,我們最好用一個通解來處理這類問題。我們可以維護一個窗口[left,right]來容納至少k個0。我們遇到了0,就累加zero的個數,然后判斷如果此時0的個數大於k,那么我們我們右移左邊界left,如果移除掉的nums[left]為0,那么我們zero自減1。如果不大於k,那么我們用窗口中數字的個數來更新res,參見代碼如下:
解法二:
class Solution { public: int findMaxConsecutiveOnes(vector<int>& nums) { int res = 0, zero = 0, left = 0, k = 1; for (int right = 0; right < nums.size(); ++right) { if (nums[right] == 0) ++zero; while (zero > k) { if (nums[left++] == 0) --zero; } res = max(res, right - left + 1); } return res; } };
上面那種方法對於follow up中的情況無法使用,因為nums[left]需要訪問之前的數字。我們可以將遇到的0的位置全都保存下來,這樣我們需要移動left的時候就知道移到哪里了:
解法三:
class Solution { public: int findMaxConsecutiveOnes(vector<int>& nums) { int res = 0, left = 0, k = 1; queue<int> q; for (int right = 0; right < nums.size(); ++right) { if (nums[right] == 0) q.push(right); if (q.size() > k) { left = q.front() + 1; q.pop(); } res = max(res, right - left + 1); } return res; } };
類似題目:
參考資料:
https://discuss.leetcode.com/topic/75439/java-concise-o-n-time-o-1-space