Flipping Bits with K-Window

Last Updated : 20 Sep, 2025

Given a binary array arr[], 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.

Try It Yourself
redirect icon

[Naive Approach] Using Nested loops - O(n*k) Time and O(1) Space

We scan the array from left to right, and whenever we see a 0, we flip the next k elements so that this 0 becomes 1. We keep doing this until we reach the last possible starting position. If at the end any 0 remains, it means it is impossible to make all elements 1; otherwise, the number of flips we made is the answer.

Working:

  • Start iterating from index 0.
  • Whenever you find arr[i] == 0, flip the next k elements by XOR with 1.
    -> This ensures the current 0 becomes 1.
  • Keep a counter (res) to track the number of flips performed.
  • At the end, check the last (k - 1) elements. If any of them is 0, return -1 (not possible).Otherwise, return the total flips.
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));

Output
4

[Better Approach] Using Running Prefix Sum - O(n) Time and O(n) Space

Instead of actually flipping k elements every time we see a 0, we use a prefix sum like trick. We maintain a flag that tells whether the current index is flipped or not, and an auxiliary flipped[] array to mark where a flip ends. This way, we avoid re-flipping the same subarray repeatedly.

Working:

  • Maintain a flag variable to indicate whether the current position is flipped or not.
  • Maintain an auxiliary array flipped[] where flipped[i] = 1 means a flip effect ends at index i.
  • Traverse the array from left to right:
    -> Update flag using flipped[i] (to cancel earlier flips).
    -> If flag == 1, toggle arr[i] (since this index is flipped).
  • If after considering flips, arr[i] == 0:
    -> Check if there are at least k elements left. If not, return -1.
    -> Increment the flip count (res).
    -> Toggle flag to apply a flip starting here.
    -> Mark flipped[i + k] = 1 to cancel this flip after k steps.
  • After the loop ends, return res as the minimum number of flips needed.
C++
#include <iostream>
#include<vector>
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));

Output
4

[Expected Approach] Using Queue - O(n) Time and O(k) Space

Instead of keeping a whole auxiliary array to mark flip boundaries, we use a queue of size at most k to track active flips. The flag variable tells whether the current element is in a flipped state. When we encounter a 0, we start a new flip of size k and mark it in the queue; when we move past that window, we remove its effect from the flag.

Working:

  • Start with res = 0 (flip count), flag = 0 (tracks if current bit is flipped), and an empty queue q.
  • For each index i in the array:
    ->If i >= k, remove the effect of the flip that started k steps ago (flag ^= q.front(); q.pop();).
    ->If flag == 1, flip the current element (arr[i] ^= 1).
    ->If arr[i] == 0, check if k elements remain; if not return -1, else increment res, toggle flag, and push 1 into q.else push 0 into q
  • After processing all elements, return res as the minimum flips.
C++
#include <iostream>
#include<vector>
#include<queue>
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
// Node class
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

// Custom Queue class
class Queue {
    constructor() {
        this.front = this.rear = null;
        this.size = 0;
    }

    isEmpty() {
        return this.size === 0;
    }

    enqueue(data) {
        const node = new Node(data);
        if (this.isEmpty()) {
            this.front = this.rear = node;
        } else {
            this.rear.next = node;
            this.rear = node;
        }
        this.size++;
    }

    dequeue() {
        if (this.isEmpty()) return null;
        const val = this.front.data;
        this.front = this.front.next;
        if (!this.front) this.rear = null;
        this.size--;
        return val;
    }
}

function kBitFlips(arr, k) {
    let n = arr.length;
    let res = 0, flag = 0;
    let q = new Queue();

    for (let i = 0; i < n; i++) {
        if (i >= k) {
            let val = q.dequeue();
            if (val !== null) flag ^= val;
        }

        // If flag = 1, flip the current index
        if (flag === 1)
            arr[i] ^= 1;

        if (arr[i] === 0) {
            if (i + k > n) return -1;

            res += 1;
            flag ^= 1;
            
            // flipped
            q.enqueue(1); 
        } else {
            
            // not flipped
            q.enqueue(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)); 

Output
4
Comment