Flipping Bits with K-Window
Last Updated :
02 Mar, 2025
Given a binary array arr[] of size n, the task is to find minimum number of operations to convert all 0s to 1s. In one operation, we can select a subarray (window) of length k
and flip all its bits. If it is impossible, return -1
.
Examples:
Input: arr[] = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1], k = 2
Output: 4
Explanation: 4 operations are required to convert all 0s to 1s:
- Flip arr[2...3], so arr[] becomes [1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1]
- Flip arr[4...5], so arr[] becomes [1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1]
- Flip arr[5...6], so arr[] becomes [1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1]
- Flip arr[6...7], so arr[] becomes [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Input: arr[] = [0, 0, 1, 1, 1, 0, 0], k = 3
Output: -1
Explanation: It is impossible to convert all elements to 1s by performing any number of operations.
[Naive Approach] Using Nested loops - O(n*k) Space and O(1) Time
The idea is to iterate from the beginning of the array and for each index i, check if arr[i] = 0 or 1. If arr[i] = 0, then flip subarray arr[i...(i+k-1)] and increment the number of operations by 1. Since, we can only flip a subarray of size k, we will iterate i only till index (n - k - 1).
After checking all elements in subarray arr[0 ... n-k-1], if there is any element which is still 0, then it is impossible to convert all elements to 1s. Otherwise, return the number of operations.
C++
#include <iostream>
#include <vector>
using namespace std;
int kBitFlips(vector<int> &arr, int k) {
int n = arr.size();
int res = 0;
for (int i = 0; i < n - k + 1; i++) {
if (arr[i] == 0) {
// if arr[i] = 0, flip arr[i...i+k-1]
for (int j = i; j < (i + k); j++)
arr[j] = 1 ^ arr[j];
res += 1;
}
}
// If arr[i] is still 0, then it is impossible
// to convert all elements to 1
for (int i = n - k + 1; i < n; i++) {
if (arr[i] == 0)
return -1;
}
return res;
}
int main() {
vector<int> arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
cout << kBitFlips(arr, k);
return 0;
}
C
#include <stdio.h>
int kBitFlips(int arr[], int n, int k) {
int res = 0;
for (int i = 0; i < n - k + 1; i++) {
if (arr[i] == 0) {
// if arr[i] = 0, flip arr[i...i+k-1]
for (int j = i; j < (i + k); j++)
arr[j] = 1 ^ arr[j];
res += 1;
}
}
// If arr[i] is still 0, then it is impossible
// to convert all elements to 1
for (int i = n - k + 1; i < n; i++) {
if (arr[i] == 0)
return -1;
}
return res;
}
int main() {
int arr[] = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 2;
printf("%d", kBitFlips(arr, n, k));
return 0;
}
Java
class GfG {
static int kBitFlips(int[] arr, int k) {
int n = arr.length;
int res = 0;
for (int i = 0; i < n - k + 1; i++) {
if (arr[i] == 0) {
// if arr[i] = 0, flip arr[i...i+k-1]
for (int j = i; j < (i + k); j++)
arr[j] = 1 ^ arr[j];
res += 1;
}
}
// If arr[i] is still 0, then it is impossible
// to convert all elements to 1
for (int i = n - k + 1; i < n; i++) {
if (arr[i] == 0)
return -1;
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
System.out.println(kBitFlips(arr, k));
}
}
Python
def kBitFlips(arr, k):
n = len(arr)
res = 0
for i in range(n - k + 1):
if arr[i] == 0:
# if arr[i] = 0, flip arr[i...i+k-1]
for j in range(i, i + k):
arr[j] = 1 ^ arr[j]
res += 1
# If arr[i] is still 0, then it is impossible
# to convert all elements to 1
for i in range(n - k + 1, n):
if arr[i] == 0:
return -1
return res
if __name__ == "__main__":
arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]
k = 2
print(kBitFlips(arr, k))
C#
using System;
class GfG {
static int kBitFlips(int[] arr, int k) {
int n = arr.Length;
int res = 0;
for (int i = 0; i < n - k + 1; i++) {
if (arr[i] == 0) {
// if arr[i] = 0, flip arr[i...i+k-1]
for (int j = i; j < (i + k); j++)
arr[j] = 1 ^ arr[j];
res += 1;
}
}
// If arr[i] is still 0, then it is impossible
// to convert all elements to 1
for (int i = n - k + 1; i < n; i++) {
if (arr[i] == 0)
return -1;
}
return res;
}
static void Main() {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
Console.WriteLine(kBitFlips(arr, k));
}
}
JavaScript
function kBitFlips(arr, k) {
let n = arr.length;
let res = 0;
for (let i = 0; i < n - k + 1; i++) {
if (arr[i] === 0) {
// if arr[i] = 0, flip arr[i...i+k-1]
for (let j = i; j < (i + k); j++) {
arr[j] = 1 ^ arr[j];
}
res += 1;
}
}
// If arr[i] is still 0, then it is impossible
// to convert all elements to 1
for (let i = n - k + 1; i < n; i++) {
if (arr[i] === 0)
return -1;
}
return res;
}
// Driver Code
let arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1];
let k = 2;
console.log(kBitFlips(arr, k));
[Better Approach] Using Running Prefix Sum - O(n) Time and O(n) Space
The idea is to solve this problem using the prefix sum technique. The idea is to avoid flipping entire subarrays repeatedly by marking the ending indices of the flip using an auxiliary array, say flipped[]. Also, maintain a flag variable that tracks the current flip state for each element.
As we iterate through the array, if an element is 0, we check if there are k elements left to flip. If so, we flip it by toggling the flag and marking the end of flip in the flipped[] array.
C++
#include <bits/stdc++.h>
using namespace std;
int kBitFlips(vector<int> &arr, int k) {
int n = arr.size();
int res = 0, flag = 0;
vector<int> flipped(n + 1, 0);
for (int i = 0; i < n; i++) {
// Check if flag should be flipped at index i
flag = (flag ^ flipped[i]);
// If flag = 1, then flip the current index
if(flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if(arr[i] == 0) {
// Check if k elements are left
if(i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1;
}
}
return res;
}
int main() {
vector<int> arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
cout << kBitFlips(arr, k);
return 0;
}
C
#include <stdio.h>
int kBitFlips(int arr[], int n, int k) {
int res = 0, flag = 0;
int flipped[n + 1];
for (int i = 0; i < n + 1; i++)
flipped[i] = 0;
for (int i = 0; i < n; i++) {
// Check if flag should be flipped at index i
flag = (flag ^ flipped[i]);
// If flag = 1, then flip the current index
if (flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] == 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1;
}
}
return res;
}
int main() {
int arr[] = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 2;
printf("%d", kBitFlips(arr, n, k));
return 0;
}
Java
class GfG {
static int kBitFlips(int[] arr, int k) {
int n = arr.length;
int res = 0, flag = 0;
int[] flipped = new int[n + 1];
for (int i = 0; i < n; i++) {
// Check if flag should be flipped at index i
flag = (flag ^ flipped[i]);
// If flag = 1, then flip the current index
if (flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] == 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
System.out.println(kBitFlips(arr, k));
}
}
Python
def kBitFlips(arr, k):
n = len(arr)
res = 0
flag = 0
flipped = [0] * (n + 1)
for i in range(n):
# Check if flag should be flipped at index i
flag ^= flipped[i]
# If flag = 1, then flip the current index
if flag == 1:
arr[i] ^= 1
# Finally, if arr[i] = 0, then we need to flip
if arr[i] == 0:
# Check if k elements are left
if i + k > n:
return -1
res += 1
# Flip flag so that upcoming elements are also flipped
flag ^= 1
# Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1
return res
if __name__ == "__main__":
arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]
k = 2
print(kBitFlips(arr, k))
C#
using System;
class GfG {
static int kBitFlips(int[] arr, int k) {
int n = arr.Length;
int res = 0, flag = 0;
int[] flipped = new int[n + 1];
for (int i = 0; i < n; i++) {
// Check if flag should be flipped at index i
flag ^= flipped[i];
// If flag = 1, then flip the current index
if (flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] == 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1;
}
}
return res;
}
static void Main() {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
Console.WriteLine(kBitFlips(arr, k));
}
}
JavaScript
function kBitFlips(arr, k) {
let n = arr.length;
let res = 0;
let flag = 0;
let flipped = new Array(n + 1).fill(0);
for (let i = 0; i < n; i++) {
// Check if flag should be flipped at index i
flag ^= flipped[i];
// If flag = 1, then flip the current index
if (flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] == 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// Mark index (i + k) where flag will be flipped again
flipped[i + k] = 1;
}
}
return res;
}
// Driver Code
let arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1];
let k = 2;
console.log(kBitFlips(arr, k));
[Expected Approach] Using Queue - O(n) Time and O(k) Space
We can further optimize the previous approach by using a queue instead of an auxiliary array. As we iterate through the array, we maintain a flag to determine whether the current element has been flipped or not. Queue is used to track flips within the current window of size k.
For each element, if it has been flipped (i.e., flag == 1), we flip it back to its original state. When encountering a 0, we check if a flip of size k is possible. If so, we flip the current element by toggling the flag, increment the flip count, and push a 1 into the queue to mark the start of the flip. If we encounter a 1, we push a 0 into the queue.
C++
#include <bits/stdc++.h>
using namespace std;
int kBitFlips(vector<int> &arr, int k) {
int n = arr.size();
int res = 0, flag = 0;
queue<int> q;
for (int i = 0; i < n; i++) {
if(i >= k) {
flag ^= q.front();
q.pop();
}
// If flag = 1, then flip the current index
if(flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if(arr[i] == 0) {
// Check if k elements are left
if(i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// If we flip, push 1 to the queue
q.push(1);
}
else {
// If we don't flip, push 0 to queue
q.push(0);
}
}
return res;
}
int main() {
vector<int> arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
cout << kBitFlips(arr, k);
return 0;
}
Java
import java.util.LinkedList;
import java.util.Queue;
class GfG {
static int kBitFlips(int[] arr, int k) {
int n = arr.length;
int res = 0, flag = 0;
Queue<Integer> q = new LinkedList<>();
for (int i = 0; i < n; i++) {
if(i >= k)
flag ^= q.poll();
// If flag = 1, then flip the current index
if(flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if(arr[i] == 0) {
// Check if k elements are left
if(i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// If we flip, push 1 to the queue
q.offer(1);
}
else {
// If we don't flip, push 0 to queue
q.offer(0);
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
System.out.println(kBitFlips(arr, k));
}
}
Python
from collections import deque
def kBitFlips(arr, k):
n = len(arr)
res = 0
flag = 0
q = deque()
for i in range(n):
if i >= k:
flag ^= q.popleft()
# If flag = 1, then flip the current index
if flag == 1:
arr[i] ^= 1
# Finally, if arr[i] = 0, then we need to flip
if arr[i] == 0:
# Check if k elements are left
if i + k > n:
return -1
res += 1
# Flip flag so that upcoming elements are also flipped
flag ^= 1
# If we flip, push 1 to the queue
q.append(1)
else:
# If we don't flip, push 0 to queue
q.append(0)
return res
if __name__ == "__main__":
arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]
k = 2
print(kBitFlips(arr, k))
C#
using System;
using System.Collections.Generic;
class GfG {
static int KBitFlips(int[] arr, int k) {
int n = arr.Length;
int res = 0, flag = 0;
Queue<int> q = new Queue<int>();
for (int i = 0; i < n; i++) {
if (i >= k) {
flag ^= q.Dequeue();
}
// If flag = 1, then flip the current index
if (flag == 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] == 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// If we flip, push 1 to the queue
q.Enqueue(1);
} else {
// If we don't flip, push 0 to queue
q.Enqueue(0);
}
}
return res;
}
static void Main() {
int[] arr = {1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1};
int k = 2;
Console.WriteLine(KBitFlips(arr, k));
}
}
JavaScript
function kBitFlips(arr, k) {
let n = arr.length;
let res = 0, flag = 0;
let q = [];
for (let i = 0; i < n; i++) {
if (i >= k) {
flag ^= q.shift();
}
// If flag = 1, then flip the current index
if (flag === 1)
arr[i] ^= 1;
// Finally, if arr[i] = 0, then we need to flip
if (arr[i] === 0) {
// Check if k elements are left
if (i + k > n)
return -1;
res += 1;
// Flip flag so that upcoming elements are also flipped
flag ^= 1;
// If we flip, push 1 to the queue
q.push(1);
} else {
// If we don't flip, push 0 to queue
q.push(0);
}
}
return res;
}
// Driver Code
let arr = [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1];
let k = 2;
console.log(kBitFlips(arr, k));
Similar Reads
Maximize the number by flipping at most K bits Given an integer N, the task is to find the greatest number that can be obtained by flipping at most K bits in the binary representation of N.Examples: Input: N = 4, K = 1 Output: 6 The binary equivalent of 4 is 100. On flipping the 1st 0, we get 110 which is equivalent to 6.Input: N = 5, K = 2 Outp
7 min read
Find the original number by flipping K unique bits Given three numbers X, Y and Z and an integer K. The number X is obtained by flipping K unique bits in the binary representation of N. Additionally, Y and Z are further obtained by flipping K unique bits in the binary representation of N. The task is to determine the original number N. Examples: Inp
7 min read
CSES Solutions - Sliding Window Cost You are given an array arr[] of N integers. Your task is to calculate for each window of K elements, from left to right, the minimum total cost of making all elements equal. You can increase or decrease each element with cost X, where X is the difference between the new and the original value. The t
12 min read
Minimum flips required to maximize a number with k set bits Given two numbers n and k, we need to find the minimum number of flips required to maximize given number by flipping its bits such that the resulting number has exactly k set bits. Note : K must be less than number of bits in n.Examples : Input : n = 14, k = 2 Output : Min Flips = 1 Explanation : Bi
7 min read
Find the minimum swaps to group K elements. Given an integer array arr[] of length n and an integer K, the task is to determine the minimum number of swaps required to group at least K occurrences of the same element consecutively in the array. If it is not possible to group the same number K times consecutive then print -1. Examples: Input:
8 min read
Rotate digits of a given number by K Given two integers N and K, the task is to rotate the digits of N by K. If K is a positive integer, left rotate its digits. Otherwise, right rotate its digits. Examples: Input: N = 12345, K = 2Output: 34512 Explanation: Left rotating N(= 12345) by K(= 2) modifies N to 34512. Therefore, the required
10 min read