📅  最后修改于: 2023-12-03 14:53:46.935000             🧑  作者: Mango
给定一个二进制数组和一个整数 K,你需要将这个数组中从 left 到 right 的位翻转(换成 1 变成 0 , 0 变成 1)。
请你返回执行 K 次翻转后的最少操作次数。
如果不能进行任何翻转,请返回 -1。
输入:arr = [0,0,0,1,0,1,1,0], k = 3
输出:3
解释:翻转位 [4,5,7](下标从 0 开始计数的)。
为了达到最小操作次数,我们需要找到最优解,那么如何计算最优解呢?
假设当前要将区间 [left, right]
全部翻转,操作次数为 1,则 [left+1, right]
全部翻转操作次数需要再加 1,而 [left, right-1]
全部翻转操作次数也需要再加 1,因为我们可以把原来需要翻转的第一个元素翻转回来,然后再把最后一个元素翻转。
因此我们想到可以使用贪心算法,从左到右扫描数组,对于每个下标 i,我们要么将 arr[i]
翻转,要么不翻转。而对于 arr[i+1]
,如果它是 0,且为使区间 [0, i]
中所有元素都为 1,我们需要将 arr[i+1]
翻转。否则,如果它是 1,且为使区间 [0, i]
中所有元素都为 0,我们需要将 arr[i+1]
翻转。注意,我们可以通过记录前面翻转的次数,来决定是否需要操作当前元素。
最终,如果 arr[right]
为 0,且区间 [0, right-1]
中所有元素都为 1,或者 arr[right]
为 1,且区间 [0, right-1]
中所有元素都为 0,则操作次数为翻转的次数;否则,不能进行任何翻转,返回 -1。
def minKBitFlips(arr, k):
n = len(arr)
cnt = 0
for i in range(n - k + 1):
if arr[i] == 0:
cnt += 1
for j in range(i, i + k):
arr[j] = 1 - arr[j]
if i == n - k:
if arr[-1] == 0:
return -1
for j in range(n - k + 1, n):
if arr[j] == 0:
return -1
return cnt