直觉

  • 本题中,我们发现对同一个位置翻转两次,等同于没有翻转。
  • 此外,对某个元素进行翻转的方式只有以下三种:
  1. 翻转当前元素
  2. 翻转当前元素的前一个
  3. 翻转当前元素的前两个
  • 这意味着一旦我们越过某个元素,就无法再对它进行翻转。

思路

  • 因此,我们可以从左到右遍历数组,对每个值为 0 的元素执行翻转,最后检查整个数组是否全为 1。
  • 为什么这个方法是正确的?

首先,我们知道一旦越过某个元素,就无法再翻转它。

这意味着当我们遍历到某个元素时,必须在此处将其翻转为 1。如果跳过这一步,该位置将永远保持 0,不满足题目要求。因此,这一步是必要操作,跳过它将无法得到目标数组。

同样可以证明,对于所有能达到目标状态的数组,这个贪心策略都能给出正确结果——因为无论执行什么操作,当前为 0 的元素都必须在此处被翻转。

复杂度

  • 时间复杂度:$O(N)$,N 为数组长度。
  • 空间复杂度:$O(1)$。

代码

class Solution:
    def minOperations(self, nums: List[int]) -> int:
        cnt = 0
        for i in range(len(nums) - 2):
            if nums[i] == 0:
                cnt += 1
                nums[i] = 1
                nums[i + 1] = 1 - nums[i + 1]
                nums[i + 2] = 1 - nums[i + 2]

        if nums[-1] == 1 and nums[-2] == 1:
            return cnt

        return -1