假设我们有一个数组A。它只包含0和1,这里的K位翻转包括选择一个长度为K的(连续)子数组,同时将子数组中的位取反。我们必须找到所需的最小K位翻转次数,以便数组中不存在0。如果没有这种可能性,则返回-1。
因此,如果输入像[0,0,0,1,0,1,1,0]且K = 3,则输出将为3,因为我们需要在第一次尝试中执行三次运算将A [0]翻转为A [3],则数组将为[1,1,1,1,0,1,1,0],第二次运行将A [4]翻转为A [6]将为[1,1,1,1,1,0,0,0],在第三步将A [5]更改为A [7]时,数组将为[1,1,1,1,1 ,, 1,1,1]。
为了解决这个问题,我们将遵循以下步骤-
n:= A的大小
定义大小为n的数组移动
计数器:= 0
对于初始化i:= 0,当i + K <= n时,更新(将i增加1),执行-
移动[i]:=移动[i] + 1
如果i + K <n,则-
(将计数器增加1)
移动[i + K]-= 1
移动[i]:=移动[i] +移动[i-1]
如果i> 0,则-
如果不是((moves [i] mod 2)+ A [i])mod 2不为零,则-
对于i <n,更新(i增加1),做-
返回-1
移动[i]:=移动[i] +移动[i-1]
如果i> 0,则-
如果不是((moves [i] mod 2)+ A [i])mod 2不为零,则-
返回柜台
让我们看下面的实现以更好地理解-
输出结果
#include <bits/stdc++.h> using namespace std; class Solution { public: int minKBitFlips(vector<int>& A, int K){ int n = A.size(); vector<int> moves(n); int i; int counter = 0; for (i = 0; i + K <= n; i++) { if (i > 0) moves[i] += moves[i - 1]; if (!(((moves[i] % 2) + A[i]) % 2)) { moves[i] += 1; if (i + K < n) moves[i + K] -= 1; counter++; } } for (; i < n; i++) { if (i > 0) moves[i] += moves[i - 1]; if (!(((moves[i] % 2) + A[i]) % 2)) return -1; } return counter; } }; main(){ Solution ob; vector<int> v = {0,0,0,1,0,1,1,0}; cout << (ob.minKBitFlips(v, 3)); }
{0,0,0,1,0,1,1,0}, 3
输出结果
3