LeetCode-995。K個の連続するビットフリップの最小数[K個の連続するビットフリップの最小数] [難易度]-分析とコード[Java]
1.トピック
0と1のみを含む配列Aでは、Kビットフリップには、長さKの(連続した)サブ配列を選択し、サブ配列の各0を1に変更し、各1を0に変更することが含まれます。
配列に値0の要素がないように、必要なKビットフリップの最小数を返します。それが不可能な場合は、-1を返します。
例1:
输入:A = [0,1,0], K = 1
输出:2
解释:先翻转 A[0],然后翻转 A[2]。
例2:
输入:A = [1,1,0], K = 2
输出:-1
解释:无论我们怎样翻转大小为 2 的子数组,我们都不能使数组变为 [1,1,1]。
例3:
输入:A = [0,0,0,1,0,1,1,0], K = 3
输出:3
解释:
翻转 A[0],A[1],A[2]: A变成 [1,1,1,1,0,1,1,0]
翻转 A[4],A[5],A[6]: A变成 [1,1,1,1,1,0,0,0]
翻转 A[5],A[6],A[7]: A变成 [1,1,1,1,1,1,1,1]
促す:
- 1 <= A.length <= 30000
- 1 <= K <= A.length
出典:LeetCode
リンク:https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips
著作権はLeetCodeが所有しています。商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。
2、分析とコード
1.スライディングウィンドウ
(1)考える
質問の意味によると、間隔ごとに1回のフリップのみが有効で、2回目は初期状態に戻ります。したがって、最初の要素が0の場合は配列の最初から開始し、次に間隔を反転できます。そうでない場合、ウィンドウは右から最後に移動します。
すべての間隔が反転した場合でも、最後のK要素には0が残っています。これは、配列要素がすべて1であることを認識できないことを示しています。
複雑さを軽減するために、現在の位置で実行されたフリップの数を記録するように数値フリップを設計できます。フリップするときは、現在の+ K位置を同期的にマークし、次の場合にフリップの数を-1に設定します。そこを横断します。
質問で指定された配列には0と1しか含まれていないため、数値+ 2をマークすることで、間隔の右の境界を反転できます。
(2)コード
class Solution {
public int minKBitFlips(int[] A, int K) {
int n = A.length, ans = 0, flip = 0;//翻转次数
for (int i = 0; i < n; i++) {
flip -= A[i] >> 1;
if (((A[i] + flip) & 1) != 1) {
//目前翻转下当前位置为1无需操作
if (i > n - K)//最后长度小于K的区间内仍有0,无法全部更改为1
return -1;
if (i + K < n)//翻转了长度为K的区间,到达区间末尾后翻转次数-1
A[i + K] -= 2;//通过对2取模避免干扰原数组中的0和1
flip++;//当前位置开始执行一次翻转
ans++;//记录翻转次数
}
}
return ans;
}
}
(3)結果
実行時間:4ミリ秒、
すべてのJava送信でユーザーの100.00%を上回っています。メモリ消費量:46.7 MB、すべてのJava送信でユーザーの25.63%を上回っています。
3、その他
何もありません。