VOOZH about

URL: https://www.geeksforgeeks.org/dsa/flipping-bits-with-k-window/

⇱ Flipping Bits with K-Window - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

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.

[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.

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.

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.

Output
4
Comment
Article Tags:
Article Tags: