Open In App

Minimize flips on K-length subarrays required to make all array elements equal to 1

Last Updated : 20 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary array arr[] of size N and a positive integer K, the task is to find the minimum number of times any subarray of size K from the given array arr[] is required to be flipped to make all array elements equal to 1. If it is not possible to do so, then print “-1”.

Examples:

Input: arr[] = {0, 1, 0}, K = 1
Output: 2
Explanation:
Perform the operation in the following order:
Operation 1: Flip all elements present in the subarray {arr[0]}. Now, the array modifies to {1, 1, 0}.
Operation 2: Flip all elements present in the subarray {arr[2]}. Now the array modifies to {1, 1, 1}.
Therefore, the total number of operations required is 2.

Input: arr[] = {1, 1, 0}, K = 2
Output: -1

 

Approach: Follow the steps below to solve the problem:

  • Initialize an auxiliary array, say isFlipped[] of size N.
  • Initialize a variable, say ans, to store the minimum number of K-length subarray flips required.
  • Traverse the given array arr[] using a variable i and perform the following steps:
    • If the value of i is greater than 0, then update the value of isFlipped[i] as (isFlipped[i] + isFlipped[i – 1])%2.
    • Check if the current element needs to be flipped, i.e. if the value of A[i] is 0 and isFlipped[i] is not set OR, the value of A[i] is 1 and isFlipped[i] is set, then perform the following steps:
      • If such a K-length subarray is not possible, then print “-1” and break out of the loop, as it is impossible to make all array elements equal to 1.
      • Increment ans and isFlipped[i] by 1, and decrement isFlipped[i + K] by 1.
    • Otherwise, continue to the next iteration.
  • After completing the above steps, if all array elements can be made 1, then print the value of ans as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to find the minimum number
// K-length subarrays required to be
// flipped to make all array elements 1
void minimumOperations(vector<int>& A, int K)
{
    // Stores whether an element
    // can be flipped or not
    vector<int> isflipped(A.size(), 0);

    // Store the required number of flips
    int ans = 0;

    // Traverse the array, A[]
    for (int i = 0; i < A.size(); i++) {

        // Find the prefix sum
        // for the indices i > 0
        if (i > 0) {
            isflipped[i] += isflipped[i - 1];
            isflipped[i] %= 2;
        }

        // Check if the current element
        // is required to be flipped
        if (A[i] == 0 && !isflipped[i]) {

            // If subarray of size K
            // is not possible, then
            // print -1 and return
            if ((A.size() - i + 1) <= K) {
                cout << -1;
                return;
            }

            // Increment ans by 1
            ans++;

            // Change the current
            // state of the element
            isflipped[i]++;

            // Decrement isFlipped[i + K]
            isflipped[i + K]--;
        }
        else if (A[i] == 1 && isflipped[i]) {

            // If subarray of size K
            // is not possible, then
            // print -1 and return
            if ((A.size() - i + 1) <= K) {
                cout << -1;
                return;
            }

            // Increment ans by 1
            ans++;

            // Change the current
            // state of the element
            isflipped[i]++;

            // Decrement isFlipped[i+K]
            isflipped[i + K]--;
        }
    }

    // Print the result
    cout << ans;
}

// Driver Code
int main()
{
    vector<int> arr = { 0, 1, 0 };
    int K = 1;
    minimumOperations(arr, K);

    return 0;
}
Java
// Java program for the above approach
class GFG
{

  // Function to find the minimum number
  // K-length subarrays required to be
  // flipped to make all array elements 1  
  static void minimumOperations(int[] A, int K) 
  {

    // Stores whether an element
    // can be flipped or not
    int[] isflipped = new int[A.length+1];

    // Store the required number of flips
    int ans = 0;

    // Traverse the array, A[]
    for (int i = 0; i < A.length; i++)
    {

      // Find the prefix sum
      // for the indices i > 0
      if (i > 0) {
        isflipped[i] += isflipped[i - 1];
        isflipped[i] %= 2;
      }

      // Check if the current element
      // is required to be flipped
      if (A[i] == 0 && isflipped[i] == 0) 
      {

        // If subarray of size K
        // is not possible, then
        // print -1 and return
        if ((A.length - i + 1) <= K) 
        {
          System.out.println(-1);
          return;
        }

        // Increment ans by 1
        ans++;

        // Change the current
        // state of the element
        isflipped[i]++;

        // Decrement isFlipped[i + K]
        isflipped[i + K]--;
      } else if (A[i] == 1 && isflipped[i] != 0)
      {

        // If subarray of size K
        // is not possible, then
        // print -1 and return
        if ((A.length - i + 1) <= K)
        {
          System.out.println(-1);
          return;
        }

        // Increment ans by 1
        ans++;

        // Change the current
        // state of the element
        isflipped[i]++;

        // Decrement isFlipped[i+K]
        isflipped[i + K]--;
      }
    }

    // Print the result
    System.out.println(ans);
  }

  // Driver Code
  public static void main(String[] args) 
  {
    int[] arr = {0, 1, 0};
    int K = 1;
    minimumOperations(arr, K);
  }
}

// This code is contributed by user_qa7r.
Python3
# Python3 program for the above approach

# Function to find the minimum number
# K-length subarrays required to be
# flipped to make all array elements 1
def minimumOperations(A, K):

    # Stores whether an element
    # can be flipped or not
    isflipped = [0] * (len(A) + 1)

    # Store the required number of flips
    ans = 0

    # Traverse the array, A[]
    for i in range(len(A)):

        # Find the prefix sum
        # for the indices i > 0
        if (i > 0):
            isflipped[i] += isflipped[i - 1]
            isflipped[i] %= 2

        # Check if the current element
        # is required to be flipped
        if (A[i] == 0 and not isflipped[i]):

            # If subarray of size K
            # is not possible, then
            # print -1 and return
            if ((len(A) - i + 1) <= K):
                print(-1)
                return

            # Increment ans by 1
            ans += 1

            # Change the current
            # state of the element
            isflipped[i] += 1

            # Decrement isFlipped[i + K]
            isflipped[i + K] -= 1

        elif (A[i] == 1 and isflipped[i]):

            # If subarray of size K
            # is not possible, then
            # print -1 and return
            if ((len(A) - i + 1) <= K):
                print(-1)
                return

            # Increment ans by 1
            ans += 1

            # Change the current
            # state of the element
            isflipped[i] += 1

            # Decrement isFlipped[i+K]
            isflipped[i + K] -= 1

    # Print the result
    print(ans)

# Driver Code
if __name__ == "__main__":

    arr = [0, 1, 0]
    K = 1
    
    minimumOperations(arr, K)

# This code is contributed by ukasp
C#
// C# program for the above approach
using System;
using System.Collections.Generic;

class GFG{
 
// Function to find the minimum number
// K-length subarrays required to be
// flipped to make all array elements 1
static void minimumOperations(List<int> A, int K)
{
    
    // Stores whether an element
    // can be flipped or not
    List<int> isflipped = new List<int>();
    for(int i = 0; i < A.Count + 1; i++)
        isflipped.Add(0);

    // Store the required number of flips
    int ans = 0;

    // Traverse the array, A[]
    for(int i = 0; i < A.Count; i++) 
    {
        
        // Find the prefix sum
        // for the indices i > 0
        if (i > 0)
        {
            isflipped[i] += isflipped[i - 1];
            isflipped[i] %= 2;
        }

        // Check if the current element
        // is required to be flipped
        if (A[i] == 0 && isflipped[i] == 0)
        {
            
            // If subarray of size K
            // is not possible, then
            // print -1 and return
            if ((A.Count - i + 1) <= K) 
            {
                Console.Write(-1);
                return;
            }

            // Increment ans by 1
            ans += 1;

            // Change the current
            // state of the element
            isflipped[i] += 1;

            // Decrement isFlipped[i + K]
            isflipped[i + K] -= 1;
        }
        else if (A[i] == 1 && isflipped[i] != 0)
        {
            
            // If subarray of size K
            // is not possible, then
            // print -1 and return
            if ((A.Count - i + 1) <= K)
            {
                Console.Write(-1);
                return;
            }

            // Increment ans by 1
            ans += 1;

            // Change the current
            // state of the element
            isflipped[i] += 1;

            // Decrement isFlipped[i+K]
            isflipped[i + K] -= 1;
        }
    }

    // Print the result
    Console.WriteLine(ans);
}

// Driver Code
public static void Main()
{
    List<int> arr = new List<int>(){ 0, 1, 0 };
    int K = 1;
    
    minimumOperations(arr, K);
}
}

// This code is contributed by bgangwar59
Javascript
<script>

// Javascript program for the above approach

  // Function to find the minimum number
  // K-length subarrays required to be
  // flipped to make all array elements 1 
  function minimumOperations(A, K)
  {
 
    // Stores whether an element
    // can be flipped or not
    let isflipped = [];
    for (let i = 0; i < A.length + 1; i++)
    {
        isflipped[i] =0;
    }
 
    // Store the required number of flips
    let ans = 0;
 
    // Traverse the array, A[]
    for (let i = 0; i < A.length; i++)
    {
 
      // Find the prefix sum
      // for the indices i > 0
      if (i > 0) {
        isflipped[i] += isflipped[i - 1];
        isflipped[i] %= 2;
      }
 
      // Check if the current element
      // is required to be flipped
      if (A[i] == 0 && isflipped[i] == 0)
      {
 
        // If subarray of size K
        // is not possible, then
        // print -1 and return
        if ((A.length - i + 1) <= K)
        {
          document.write(-1);
          return;
        }
 
        // Increment ans by 1
        ans++;
 
        // Change the current
        // state of the element
        isflipped[i]++;
 
        // Decrement isFlipped[i + K]
        isflipped[i + K]--;
      } else if (A[i] == 1 && isflipped[i] != 0)
      {
 
        // If subarray of size K
        // is not possible, then
        // print -1 and return
        if ((A.length - i + 1) <= K)
        {
          document.write(-1);
          return;
        }
 
        // Increment ans by 1
        ans++;
 
        // Change the current
        // state of the element
        isflipped[i]++;
 
        // Decrement isFlipped[i+K]
        isflipped[i + K]--;
      }
    }
 
    // Print the result
    document.write(ans);
  }


// Driver Code

    let arr = [ 0, 1, 0 ];
    let K = 1;
    minimumOperations(arr, K);

</script>

Output
2

Time Complexity: O(N)
Auxiliary Space: O(N)

Approach 2:- Sliding Window

C++
#include <bits/stdc++.h>
using namespace std;

int minKBitFlips(int A[], int K, int N)
{
  
    // store previous flip events
    queue<int> flip;
    int count = 0;
    for (int i = 0; i < N; i++) 
    {
      
        // remove an item which is out range of window.
        if (flip.size() > 0 && (i - flip.front() >= K)) {
            flip.pop();
        }
      
        /*
         In a window,  if A[i] is a even number with
         even times flipped, it need to be flipped again.
         On other hand,if A[i] is a odd number with odd
         times flipped, it need to be flipped again.
        */
        if (A[i] % 2 == flip.size() % 2) {
            if (i + K - 1 >= N) {
                return -1;
            }
            flip.push(i); // insert
            count++;
        }
    }
    return count;
}
    
int main()
{
    int A[] = { 0, 1, 0 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 1;
    int ans = minKBitFlips(A, K, 3);
    cout << ans;

    return 0;
}

// This code is contributed by divyeshrabadiya07.
Java
/*package whatever //do not write package name here */

import java.io.*;
import java.util.*;

class GFG {
    static int minKBitFlips(int[] A, int K)
    {
        // store previous flip events
        Queue<Integer> flip = new LinkedList<>();
        int count = 0;
        for (int i = 0; i < A.length; i++) {
            // remove an item which is out range of window.
            if (!flip.isEmpty() && (i - flip.peek() >= K)) {
                flip.poll();
            }
            /*
             In a window,  if A[i] is a even number with
             even times flipped, it need to be flipped again.
             On other hand,if A[i] is a odd number with odd
             times flipped, it need to be flipped again.
            */
            if (A[i] % 2 == flip.size() % 2) {
                if (i + K - 1 >= A.length) {
                    return -1;
                }
                flip.offer(i); // insert
                count++;
            }
        }
        return count;
    }
    public static void main(String[] args)
    {
        int[] A = { 0, 1, 0 };
        int K = 1;
        int ans = minKBitFlips(A, K);
        System.out.println(ans);
    }
}
Python3
def minKBitFlips(A, K, N):
    
    # Store previous flip events
    flip = []
    count = 0
    
    for i in range(N):
        
        # Remove an item which is out range of window.
        if (len(flip) > 0 and (i - flip[0] >= K)):
            flip.pop(0)
    
        """
        In a window, if A[i] is a even number with
        even times flipped, it need to be flipped again.
        On other hand,if A[i] is a odd number with odd
        times flipped, it need to be flipped again.
        """
        if (A[i] % 2 == len(flip) % 2):
            if (i + K - 1 >= N):
                return -1
                
            # Insert
            flip.append(i) 
            count += 1
            
    return count

# Driver code
A = [ 0, 1, 0 ]
N = len(A) 
K = 1

ans = minKBitFlips(A, K, 3)

print(ans)

# This code is contributed by rameshtravel07
C#
using System;
using System.Collections;
class GFG {
    
    static int minKBitFlips(int[] A, int K)
    {
      
        // store previous flip events
        Queue flip = new Queue();
        int count = 0;
        for (int i = 0; i < A.Length; i++)
        {
          
            // remove an item which is out range of window.
            if (flip.Count > 0 && (i - (int)flip.Peek() >= K)) {
                flip.Dequeue();
            }
          
            /*
             In a window,  if A[i] is a even number with
             even times flipped, it need to be flipped again.
             On other hand,if A[i] is a odd number with odd
             times flipped, it need to be flipped again.
            */
            if (A[i] % 2 == flip.Count % 2) {
                if (i + K - 1 >= A.Length) {
                    return -1;
                }
                flip.Enqueue(i); // insert
                count++;
            }
        }
        return count;
    }
    
  static void Main() {
    int[] A = { 0, 1, 0 };
    int K = 1;
    int ans = minKBitFlips(A, K);
    Console.WriteLine(ans);
  }
}

// This code is contributed by mukesh07.
Javascript
<script>

function minKBitFlips(A,K)
{
    // store previous flip events
        let flip = [];
        let count = 0;
        for (let i = 0; i < A.length; i++) {
            // remove an item which is out range of window.
            if (flip.length!=0 && (i - flip[0] >= K)) {
                flip.shift();
            }
            /*
             In a window,  if A[i] is a even number with
             even times flipped, it need to be flipped again.
             On other hand,if A[i] is a odd number with odd
             times flipped, it need to be flipped again.
            */
            if (A[i] % 2 == flip.length % 2) {
                if (i + K - 1 >= A.length) {
                    return -1;
                }
                flip.push(i); // insert
                count++;
            }
        }
        return count;
}

let A=[0, 1, 0 ];
let K = 1;
let ans = minKBitFlips(A, K);
document.write(ans);


// This code is contributed by avanitrachhadiya2155

</script>

Output
2

Complexity Analysis:-

Time Complexity: O(N), where N is the length of the array.

Space Complexity: O(N).

Approach 3:- Greedy

C++
#include <bits/stdc++.h>
using namespace std;

int minKBitFlips(vector<int>& A, int K) {
    int N = A.size(); // Size of the input array
    vector<int> flip(N, 0); // Array to keep track of flips
    int ans = 0, rev = 0; // Initialize answer and rev (to keep track of current number of flips)

    // Iterate over the array
    for (int i = 0; i < N; ++i) {
        // If we are beyond K elements, update rev from flip array
        if (i >= K)
            rev ^= flip[i - K];

        // If the current number of flips is odd and the current element is 1,
        // or if the current number of flips is even and the current element is 0,
        // then we need to flip the current subarray
        if (rev % 2 == A[i]) {
            // If the subarray ends beyond the array, return -1
            if (i + K > N)
                return -1;

            // Increment our answer and update our flip array and rev variable
            ans++;
            rev ^= 1;
            flip[i] = 1;
        }
    }

    // Return the minimum number of flips required
    return ans;
}

int main() {
    vector<int> A = {0, 0, 1, 0, 0};
    int K = 5;
    int ans = minKBitFlips(A, K); 
    cout << ans;

    return 0;
}
Java
/*package whatever //do not write package name here */

import java.io.*;
import java.util.*;

class GFG {
    static int minKBitFlips(int[] A, int K)
    {
        int[] temp = new int[A.length];
        int count = 0;
        int flip = 0;
        for (int i = 0; i < A.length; ++i) {
            flip ^= temp[i];
            if (A[i] == flip) { // If we must flip the
                                // subarray starting here...
                count++; // We're flipping the subarray from
                         // A[i] to A[i+K-1]
                if (i + K > A.length) {
                    return -1; // If we can't flip the
                               // entire subarray, its
                               // impossible
                }
                flip ^= 1;
                if (i + K < A.length) {
                    temp[i + K] ^= 1;
                }
            }
        }

        return count;
    }
    public static void main(String[] args)
    {
        int[] A = { 0, 1, 0 };
        int K = 1;
        int ans = minKBitFlips(A, K);
        System.out.println(ans);
    }
}
Python3
def minKBitFlips(A, K):

    temp = [0]*len(A)
    count = 0
    flip = 0
    for i in range(len(A)):
        flip ^= temp[i]
        if (A[i] == flip):
          
            # If we must flip the
            # subarray starting here...
            count += 1
            
            # We're flipping the subarray from
            # A[i] to A[i+K-1]
            if (i + K > len(A)) :
                return -1 
              
                # If we can't flip the
                # entire subarray, its
                # impossible
            
            flip ^= 1
            if (i + K < len(A)):
                temp[i + K] ^= 1

    return count
    
A = [ 0, 1, 0 ]
K = 1
ans = minKBitFlips(A, K)
print(ans)

# This code is contributed by divyesh072019.
C#
/*package whatever //do not write package name here */

using System;

class GFG {
    static int minKBitFlips(int[] A, int K)
    {
        int[] temp = new int[A.Length];
        int count = 0;
        int flip = 0;
        for (int i = 0; i < A.Length; ++i) {
            flip ^= temp[i];
            if (A[i] == flip) { // If we must flip the
                                // subarray starting here...
                count++; // We're flipping the subarray from
                         // A[i] to A[i+K-1]
                if (i + K > A.Length) {
                    return -1; // If we can't flip the
                               // entire subarray, its
                               // impossible
                }
                flip ^= 1;
                if (i + K < A.Length) {
                    temp[i + K] ^= 1;
                }
            }
        }

        return count;
    }
    public static void Main(String[] args)
    {
        int[] A = { 0, 1, 0 };
        int K = 1;
        int ans = minKBitFlips(A, K);
        Console.Write(ans);
    }
}

// This code is contributed by shivanisinghss2110
Javascript
<script>
    function minKBitFlips(A, K)
    {
        let temp = new Array(A.length);
        let count = 0;
        let flip = 0;
        for (let i = 0; i < A.length; ++i) {
            flip ^= temp[i];
            if (A[i] == flip) { // If we must flip the
                                // subarray starting here...
                count++; // We're flipping the subarray from
                         // A[i] to A[i+K-1]
                if (i + K > A.length) {
                    return -1; // If we can't flip the
                               // entire subarray, its
                               // impossible
                }
                flip ^= 1;
                if (i + K < A.length) {
                    temp[i + K] ^= 1;
                }
            }
        }
 
        return count;
    }
    
    let A = [ 0, 1, 0 ];
    let K = 1;
    let ans = minKBitFlips(A, K);
    document.write(ans);
 
 // This code is contributed by gfgking.
</script>

Output
2

Complexity Analysis:-

Time Complexity: O(N), where N is the length of the array.

Space Complexity: O(N).

Related Topic: Subarrays, Subsequences, and Subsets in Array



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads