Leetcode日练笔记19 #487 Max Consecutive Ones II (Medium)

#487 Max Consecutive Ones II (Medium)

Given a binary array nums, return the maximum number of consecutive 1's in the array if you can flip at most one 0.

解题思路:

因为最多可以翻转一个0,那么等同于0所包围的1可以看成可用于加法的有效片段。结果就是取邻近的两个片段之和的最大值再加1。

edge case是,整个数列没有0,或者只有1个0,那么结果直接是数列的长度。

有效片段的长度,用one_counter来统计。因为还要考虑0的长度,zero_counter,如果超过1,那么两个片段之间就不可以相加。用prev来储存上一个有效片段的长度值,用于和当前的one_counter相加,相加之和与之前邻近片段之和作对比,取最大值。

直到数列的最后一个数值。如果最后一个数值为1,那么当前的one_counter还没有参与到相加的运算中,所以要补一步。如果最后一个数值为0,那么已经当前的one_counter已经参与了,没有浪费。

(步骤有点繁琐,可能问题拆解还不是最优解。要参考一下其他solution)

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        if 0 not in nums or nums.count(0) == 1:
            return len(nums)
            
        
        one_counter = zero_counter = prev = addition = 0
        for i in nums:
            if i == 1:
                one_counter += 1
                zero_counter = 0
            else:
                zero_counter += 1
                if zero_counter > 1:
                    prev = 0
                if one_counter != 0:
                    addition = max(addition, prev + one_counter)
                    prev, one_counter = one_counter, 0
        if one_counter != 0:
            addition = max(addition, prev + one_counter)
         
        return addition+1

 runtime:

Leetcode日练笔记19 #487 Max Consecutive Ones II (Medium)_第1张图片

Discussion Forum里cmc也是这个思路,分为prev和curr。但是没有那么复杂。暂时还没看懂,怎么处理很多个0间隔的,以及整个数列只有1个0或没有0的情况。

class Solution(object):
    def findMaxConsecutiveOnes(self, nums):
        # previous and current length of consecutive 1 
        pre, curr, maxlen = -1, 0, 0
        for n in nums:
            if n == 0:
                pre, curr = curr, 0
            else:
                curr += 1
            maxlen = max(maxlen, pre + 1 + curr )
        
        return maxlen

绝了。总算看懂。通过把pre设为-1,来解决数列中没有0或者只有1个0的情况。确实也make sense。如果一直没有遇到零,那么就不存在prev,上一个有效片段。如果只存在1个0,那么当下的有效片段,curr就是0,如果遇到第二个0,就通过把curr的0值给到prev,来清空prev的值。所以其实没有必要统计0的个数。通过当前输入的数为0,来控制prev和curr的应有值。

还有个和之前思路的最大的不同,是把提取两者之和的最大值放在了遇到1的时候做,我之前是遇到0的时候才做。所以放在遇到1的时候执行,就不必在区分最后一个数为0还是1,不存在漏掉curr的情况。也就没有重复max()这个语句。

再重写一遍:

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        prev, counter, longest = -1, 0, 0
        for i in nums:
            if i == 0:
                prev, counter = counter, 0
            else:
                counter += 1
            longest = max(longest, prev + counter + 1)
        
        return longest

(倒着推能看懂,但是不看的话,真的很难自己总结出这样的思路……还是水平没到

 runtime:

Leetcode日练笔记19 #487 Max Consecutive Ones II (Medium)_第2张图片

一定要二刷和多看的题。

你可能感兴趣的:(leetcode日练,leetcode,算法,职场和发展)