思路一:滑动窗口
首先考虑第一个位置,只有一个窗口能翻转它。所以第一个窗口必须满足第一个位置。然后再看第二个元素,只有第一,第二个窗口能满足,第一个窗口是否翻转是固定的,所以第二个窗口是否翻转也固定,这样窗口一直滑动,咱们只需关心窗口的第一个元素就好。
class Solution:
def minKBitFlips(self, A: List[int], K: int) -> int:
ret = 0
for i in range(len(A)-K+1):
if A[i] == 0:
ret += 1
for j in range(i+1, i+K):
A[j] = 1 - A[j]
for i in range(len(A)-K+1, len(A)):
if A[i] == 0: return -1
return ret
思路二:时间优化
提交后发现超时,说明需要O(N)的算法,即要用O(1)的时间复杂度记录每次翻转情况。关键在于,我们关心每个元素的前K个元素翻转了多少次。我们可以用一个队列把前K个元素翻转了的入队,然后用队列长度看这个元素是否需要翻转。
from heapq import *
class Solution:
def minKBitFlips(self, A: List[int], K: int) -> int:
ret = 0
q = []
heapify(q)
for i in range(len(A)-K+1):
if len(q) and i-q[0] >= K: heappop(q)
if len(q)&1: A[i] = 1 - A[i]
if A[i] == 0:
ret += 1
heappush(q, i)
for i in range(len(A)-K+1, len(A)):
if len(q) and i-q[0] >= K: heappop(q)
if A[i] == len(q)&1: return -1
return ret