Find zeroes to be flipped so that number of consecutive 1’s is maximized

29 Jun, 2022
Given a binary array and an integer m, find the position of zeroes flipping which creates maximum number of consecutive 1’s in array.
Examples : 
Input:   arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}
         m = 2
Output:  5 7
We are allowed to flip maximum 2 zeroes. If we flip
arr[5] and arr[7], we get 8 consecutive 1's which is
maximum possible under given constraints 

Input:   arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}
         m = 1
Output:  7
We are allowed to flip maximum 1 zero. If we flip 
arr[7], we get 5 consecutive 1's which is maximum 
possible under given constraints.

Input:   arr[] = {0, 0, 0, 1}
         m = 4
Output:  0 1 2
Since m is more than number of zeroes, we can flip
all zeroes.
A Simple Solution is to consider every subarray by running two loops. For every subarray, count number of zeroes in it. Return the maximum size subarray with m or less zeroes. Time Complexity of this solution is O(n2).
A Better Solution is to use auxiliary space to solve the problem in O(n) time.
For all positions of 0’s calculate left[] and right[] which defines the number of consecutive 1’s to the left of i and right of i respectively. 
For example, for arr[] = {1, 1, 0, 1, 1, 0, 0, 1, 1, 1} and m = 1, left[2] = 2 and right[2] = 2, left[5] = 2 and right[5] = 0, left[6] = 0 and right[6] = 3.
left[] and right[] can be filled in O(n) time by traversing array once and keeping track of last seen 1 and last seen 0. While filling left[] and right[], we also store indexes of all zeroes in a third array say zeroes[]. For above example, this third array stores {2, 5, 6}
Now traverse zeroes[] and for all consecutive m entries in this array, compute the sum of 1s that can be produced. This step can be done in O(n) using left[] and right[]. 
Implementation:
C++
Java
Python3
C#
Javascript
// C++ program to find positions of zeroes flipping which// produces maximum number of consecutive 1's#include <bits/stdc++.h>using namespace std; // m is maximum of number zeroes allowed to flip// n is size of arrayvector<int> maximized_one(int arr[], int n, int m){    // Left array    int left[n] = { 0 };    // Right array    int right[n] = { 0 };    // Array will contain zeroes position    vector<int> zero_pos;    // Stores count    int count = 0;    int previous_index_of_zero = -1;    for (int i = 0; i < n; i++) {        if (arr[i]) {            count++;        }        else {            left[i] = count;            zero_pos.push_back(i);            if (previous_index_of_zero != i                && previous_index_of_zero != -1) {                right[previous_index_of_zero] = count;            }            count = 0;            // To keep track of the previous index of zeroes            previous_index_of_zero = i;        }    }    right[previous_index_of_zero] = count;     int max_one = -1;    vector<int> result_index;    int i = 0;     while (i <= (zero_pos.size()) - m) {        int temp = 0;        vector<int> index;         for (int c = 0; c < m; c++) {            temp += left[zero_pos[i + c]]                    + right[zero_pos[i + c]] + 1;            // Index is updated            index.push_back(zero_pos[i + c]);        }        // Decrement temp by m-1 because when we are        // calculating temp we are adding 1 in it. So, in        // order to get exact count of 1. This decrement is        // applicable only when value of m is greater than 1        temp = temp - (m - 1);        // Updating max value when we get the new max temp        // and result_index as well        if (temp > max_one) {            max_one = temp;            result_index = index;        }        i += 1;    }     return result_index;}// Driver programint main(){    int arr[] = { 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1 };    int m = 2;    int n = sizeof(arr) / sizeof(arr[0]);    cout << "Index of zeroes that are flipped: ";    vector<int> result_index = maximized_one(arr, n, m);    for (auto i : result_index) {        cout << i << " ";    }    return 0;}
// Java program to find positions of zeroes flipping which// produces maximum number of consecutive 1's import java.util.*; class GFG{ // m is maximum of number zeroes allowed to flip// n is size of arraystatic Vector<Integer> maximized_one(int arr[], int n, int m){    // Left array    int left[] = new int[n];    // Right array    int right[] = new int[n];    // Array will contain zeroes position    Vector<Integer> zero_pos = new Vector<>();    // Stores count    int count = 0;    int previous_index_of_zero = -1;    for (int i = 0; i < n; i++) {        if (arr[i]!=0) {            count++;        }        else {            left[i] = count;            zero_pos.add(i);            if (previous_index_of_zero != i                && previous_index_of_zero != -1) {                right[previous_index_of_zero] = count;            }            count = 0;            // To keep track of the previous index of zeroes            previous_index_of_zero = i;        }    }    right[previous_index_of_zero] = count;     int max_one = -1;    Vector<Integer> result_index = new Vector<>();    int i = 0;     while (i <= (zero_pos.size()) - m) {        int temp = 0;        Vector<Integer> index = new Vector<>();         for (int c = 0; c < m; c++) {            temp += left[zero_pos.elementAt(i + c)]                    + right[zero_pos.elementAt(i + c)] + 1;            // Index is updated            index.add(zero_pos.elementAt(i + c));        }        // Decrement temp by m-1 because when we are        // calculating temp we are adding 1 in it. So, in        // order to get exact count of 1. This decrement is        // applicable only when value of m is greater than 1        temp = temp - (m - 1);        // Updating max value when we get the new max temp        // and result_index as well        if (temp > max_one) {            max_one = temp;            result_index = index;        }        i += 1;    }     return result_index;}// Driver programpublic static void main(String[] args){    int arr[] = { 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1 };    int m = 2;    int n = arr.length;    System.out.print("Index of zeroes that are flipped: [");    Vector<Integer> result_index = maximized_one(arr, n, m);    for (int i : result_index) {        System.out.print(i+ " ");    }    System.out.print("]");}} // This code contributed by umadevi9616
# Python3 code for the above approach def maximized_one(arr,n,m):       # Left array    left = [0]*n         # Right array    right = [0]*n               # Array will contain zeroes position    zero_pos = []               # Stores count    count = 0              previous_index_of_zero = -1    for i in range(n):        if arr[i] == 1:            count+=1        if arr[i] == 0:            left[i] = count            zero_pos.append(i)            if previous_index_of_zero !=i and previous_index_of_zero!=-1:                right[previous_index_of_zero] = count            count = 0                         # To keep track of the previous index of zeroes            previous_index_of_zero = i             right[previous_index_of_zero] = count          # print(left)    # print(right)    # print(zero_pos)    max_one = -1    result_index = 0    i=0    while(i<=len(zero_pos)-m):        temp = 0        index = []        for c in range(m):                       # print(zero_pos[i+c],left[zero_pos[i+c]],right[zero_pos[i+c]])            temp += left[zero_pos[i+c]] + right[zero_pos[i+c]] +1                         # Index is updated            index.append(zero_pos[i+c])                      # Decrement temp by m-1 because when we are calculating temp        # we are adding 1 in it.        # So, in order to get exact count of 1.        # This decrement is applicable only when value of m is greater than 1        temp = temp-(m-1)                 # Updating max value when we get the new max temp        # and result_index as well        if temp > max_one:                             max_one = temp            result_index = index        i+=1             return result_index      # Driver Codeif __name__ == '__main__':    arr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1]    n = len(arr)    m = 2    print('Index of zeroes that are flipped: ',maximized_one(arr,n,m))
// C# program to find positions of zeroes flipping which// produces maximum number of consecutive 1'susing System;using System.Collections.Generic; public class GFG{ // m is maximum of number zeroes allowed to flip// n is size of arraystatic List<int> maximized_one(int []arr, int n, int m){    // Left array    int []left = new int[n];       // Right array    int []right = new int[n];       // Array will contain zeroes position    List<int> zero_pos = new List<int>();       // Stores count    int count = 0;    int previous_index_of_zero = -1;    for (int j = 0; j < n; j++) {        if (arr[j] != 0) {            count++;        }        else {            left[j] = count;            zero_pos.Add(j);            if (previous_index_of_zero != j                && previous_index_of_zero != -1) {                right[previous_index_of_zero] = count;            }            count = 0;                       // To keep track of the previous index of zeroes            previous_index_of_zero = j;        }    }    right[previous_index_of_zero] = count;     int max_one = -1;    List<int> result_index = new List<int>();    int i = 0;     while (i <= (zero_pos.Count) - m) {        int temp = 0;        List<int> index = new List<int>();         for (int c = 0; c < m; c++) {            temp += left[zero_pos[i + c]]                    + right[zero_pos[i + c]] + 1;                       // Index is updated            index.Add(zero_pos[i + c]);        }               // Decrement temp by m-1 because when we are        // calculating temp we are adding 1 in it. So, in        // order to get exact count of 1. This decrement is        // applicable only when value of m is greater than 1        temp = temp - (m - 1);               // Updating max value when we get the new max temp        // and result_index as well        if (temp > max_one) {            max_one = temp;            result_index = index;        }        i += 1;    }     return result_index;}   // Driver programpublic static void Main(String[] args){    int []arr = { 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1 };    int m = 2;    int n = arr.Length;    Console.Write("Index of zeroes that are flipped: [");    List<int> result_index = maximized_one(arr, n, m);    foreach (int i in result_index) {        Console.Write(i+ " ");    }    Console.Write("]");}} // This code is contributed by umadevi9616
<script>// javascript program to find positions of zeroes flipping which// produces maximum number of consecutive 1's   // m is maximum of number zeroes allowed to flip    // n is size of array    function maximized_one(arr, n, m)    {             // Left array        var left = Array(n).fill(0);                 // Right array        var right = Array(n).fill(0);                 // Array will contain zeroes position        var zero_pos = new Array();                 // Stores count        var count = 0;        var previous_index_of_zero = -1;        for (var i = 0; i < n; i++) {            if (arr[i] != 0) {                count++;            } else {                left[i] = count;                zero_pos.push(i);                if (previous_index_of_zero != i && previous_index_of_zero != -1) {                    right[previous_index_of_zero] = count;                }                count = 0;                // To keep track of the previous index of zeroes                previous_index_of_zero = i;            }        }        right[previous_index_of_zero] = count;         var max_one = -1;        var result_index = Array();        var i = 0;         while (i <= (zero_pos.length) - m) {            var temp = 0;            var index =  Array();             for (var c = 0; c < m; c++)            {                temp += left[zero_pos[i + c]] + right[zero_pos[i + c]] + 1;                                 // Index is updated                index.push(zero_pos[i + c]);            }                         // Decrement temp by m-1 because when we are            // calculating temp we are adding 1 in it. So, in            // order to get exact count of 1. This decrement is            // applicable only when value of m is greater than 1            temp = temp - (m - 1);                         // Updating max value when we get the new max temp            // and result_index as well            if (temp > max_one) {                max_one = temp;                result_index = index;            }            i += 1;        }         return result_index;    }     // Driver program        var arr = [ 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1 ];        var m = 2;        var n = arr.length;        document.write("Index of zeroes that are flipped: [");        var result_index = maximized_one(arr, n, m);        for (var i = 0; i < result_index.length; i++) {            document.write(result_index[i] + " ");        }        document.write("]"); // This code is contributed by gauravrajput1</script>
Index of zeroes that are flipped:  [5, 7]
Time Complexity: O(n)Auxiliary Space: O(n)
An Efficient Solution can solve the problem in O(n) time and O(1) space. The idea is to use Sliding Window for the given array.
Let us use a window covering from index wL to index wR. Let the number of zeros inside the window be zeroCount. We maintain the window with at most m zeros inside.
The main steps are: 
While zeroCount is no more than m: expand the window to the right (wR++) and update the count zeroCount. 
While zeroCount exceeds m, shrink the window from left (wL++), update zeroCount; 
Update the widest window along the way. The positions of output zeros are inside the best window.
Below is the implementation of the idea. 
C++
Java
Python3
C#
PHP
Javascript
// C++ program to find positions of zeroes flipping which// produces maximum number of consecutive 1's#include<bits/stdc++.h>using namespace std; // m is maximum of number zeroes allowed to flip// n is size of arrayvoid findZeroes(int arr[], int n, int m){    // Left and right indexes of current window    int wL = 0, wR = 0;     // Left index and size of the widest window    int bestL = 0, bestWindow = 0;     // Count of zeroes in current window    int zeroCount = 0;     // While right boundary of current window doesn't cross    // right end    while (wR < n)    {        // If zero count of current window is less than m,        // widen the window toward right        if (zeroCount <= m)        {            if (arr[wR] == 0)              zeroCount++;            wR++;        }         // If zero count of current window is more than m,        // reduce the window from left        if (zeroCount > m)        {            if (arr[wL] == 0)              zeroCount--;            wL++;        }         // Update widest window if this window size is more        if ((wR-wL > bestWindow) && (zeroCount<=m))        {            bestWindow = wR-wL;            bestL = wL;        }    }     // Print positions of zeroes in the widest window    for (int i=0; i<bestWindow; i++)    {        if (arr[bestL+i] == 0)           cout << bestL+i << " ";    }} // Driver programint main(){   int arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1};   int m = 2;   int n =  sizeof(arr)/sizeof(arr[0]);   cout << "Indexes of zeroes to be flipped are ";   findZeroes(arr, n, m);   return 0;}
//Java to find positions of zeroes flipping which// produces maximum number of consecutive 1'sclass Test{    static int arr[] = new int[]{1, 0, 0, 1, 1, 0, 1, 0, 1, 1};         // m is maximum of number zeroes allowed to flip    static void findZeroes(int m)    {        // Left and right indexes of current window        int wL = 0, wR = 0;             // Left index and size of the widest window        int bestL = 0, bestWindow = 0;             // Count of zeroes in current window        int zeroCount = 0;             // While right boundary of current window doesn't cross        // right end        while (wR < arr.length)        {            // If zero count of current window is less than m,            // widen the window toward right            if (zeroCount <= m)            {                if (arr[wR] == 0)                zeroCount++;                wR++;            }                 // If zero count of current window is more than m,            // reduce the window from left            if (zeroCount > m)            {                if (arr[wL] == 0)                zeroCount--;                wL++;            }                 // Update widest window if this window size is more            if ((wR-wL > bestWindow) && (zeroCount<=m))            {                bestWindow = wR-wL;                bestL = wL;            }        }             // Print positions of zeroes in the widest window        for (int i=0; i<bestWindow; i++)        {            if (arr[bestL+i] == 0)            System.out.print(bestL+i + " ");        }    }         // Driver method to test the above function    public static void main(String[] args)    {        int m = 2;        System.out.println("Indexes of zeroes to be flipped are ");                 findZeroes(m);    }}
# Python3 program to find positions# of zeroes flipping which produces# maximum number of consecutive 1's # m is maximum of number zeroes allowed# to flip, n is size of arraydef findZeroes(arr, n, m) :         # Left and right indexes of current window    wL = wR = 0     # Left index and size of the widest window    bestL = bestWindow = 0     # Count of zeroes in current window    zeroCount = 0     # While right boundary of current    # window doesn't cross right end    while wR < n:                 # If zero count of current window is less than m,        # widen the window toward right        if zeroCount <= m :            if arr[wR] == 0 :                zeroCount += 1            wR += 1         # If zero count of current window is more than m,        # reduce the window from left        if zeroCount > m :            if arr[wL] == 0 :                zeroCount -= 1            wL += 1         # Update widest window if        # this window size is more        if (wR-wL > bestWindow) and (zeroCount<=m) :            bestWindow = wR - wL            bestL = wL     # Print positions of zeroes    # in the widest window    for i in range(0, bestWindow):        if arr[bestL + i] == 0:            print (bestL + i, end = " ") # Driver programarr = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1]m = 2n = len(arr)print ("Indexes of zeroes to be flipped are", end = " ")findZeroes(arr, n, m) # This code is contributed by Shreyanshi Arun.
// C# to find positions of zeroes flipping which// produces maximum number of consecutive 1'susing System; class Test{    static int []arr = new int[]{1, 0, 0, 1, 1,                                0, 1, 0, 1, 1};         // m is maximum of number zeroes allowed to flip    static void findZeroes(int m)    {        // Left and right indexes of current window        int wL = 0, wR = 0;             // Left index and size of the widest window        int bestL = 0, bestWindow = 0;             // Count of zeroes in current window        int zeroCount = 0;             // While right boundary of current        // window doesn't cross right end        while (wR < arr.Length)        {            // If zero count of current window is less            // than m, widen the window toward right            if (zeroCount <= m)            {                if (arr[wR] == 0)                zeroCount++;                wR++;            }                 // If zero count of current window is more than m,            // reduce the window from left            if (zeroCount > m)            {                if (arr[wL] == 0)                zeroCount--;                wL++;            }                 // Update widest window if this window size is more            if ((wR-wL > bestWindow) && (zeroCount<=m))            {                bestWindow = wR-wL;                bestL = wL;            }        }             // Print positions of zeroes in the widest window        for (int i = 0; i < bestWindow; i++)        {            if (arr[bestL + i] == 0)            Console.Write(bestL + i + " ");        }    }         // Driver method to test the above function    public static void Main(String[] args)    {        int m = 2;        Console.Write("Indexes of zeroes to be flipped are ");        findZeroes(m);    }} // This code is contributed by parashar
<?php// PHP program to find positions of// zeroes flipping which produces// maximum number of consecutive 1's // m is maximum of number zeroes// allowed to flip n is size of arrayfunction findZeroes($arr, $n, $m){         // Left and right indexes    // of current window    $wL = 0;    $wR = 0;     // Left index and size of    // the widest window    $bestL = 0;    $bestWindow = 0;     // Count of zeroes in    // current window    $zeroCount = 0;     // While right boundary of    // current window doesn't cross    // right end    while ($wR < $n)    {                 // If zero count of current        // window is less than m,        // widen the window toward right        if ($zeroCount <= $m)        {            if ($arr[$wR] == 0)            $zeroCount++;            $wR++;        }         // If zero count of current        // window is more than m,        // reduce the window from left        if ($zeroCount > $m)        {            if ($arr[$wL] == 0)            $zeroCount--;            $wL++;        }         // Update widest window if        // this window size is more        if (($wR-$wL > $bestWindow) && ($zeroCount<=$m))        {            $bestWindow = $wR - $wL;            $bestL = $wL;        }    }     // Print positions of zeroes    // in the widest window    for($i = 0; $i < $bestWindow; $i++)    {        if ($arr[$bestL + $i] == 0)        echo $bestL + $i . " ";    }}     // Driver Code    $arr = array(1, 0, 0, 1, 1, 0, 1, 0, 1, 1);    $m = 2;    $n = sizeof($arr)/sizeof($arr[0]);    echo "Indexes of zeroes to be flipped are ";    findZeroes($arr, $n, $m);    return 0; // This code is contributed by nitin mittal.?>
<script>// Javascript program to find positions of// zeroes flipping which produces// maximum number of consecutive 1's // m is maximum of number zeroes// allowed to flip n is size of arrayfunction findZeroes(arr, n, m) {     // Left and right indexes    // of current window    let wL = 0;    let wR = 0;     // Left index and size of    // the widest window    let bestL = 0;    let bestWindow = 0;     // Count of zeroes in    // current window    let zeroCount = 0;     // While right boundary of    // current window doesn't cross    // right end    while (wR < n) {         // If zero count of current        // window is less than m,        // widen the window toward right        if (zeroCount <= m) {            if (arr[wR] == 0)                zeroCount++;            wR++;        }         // If zero count of current        // window is more than m,        // reduce the window from left        if (zeroCount > m) {            if (arr[wL] == 0)                zeroCount--;            wL++;        }         // Update widest window if        // this window size is more        if ((wR - wL > bestWindow) && (zeroCount <= m)) {            bestWindow = wR - wL;            bestL = wL;        }    }     // Print positions of zeroes    // in the widest window    for (let i = 0; i < bestWindow; i++) {        if (arr[bestL + i] == 0)            document.write(bestL + i + " ");    }} // Driver Codelet arr = new Array(1, 0, 0, 1, 1, 0, 1, 0, 1, 1);let m = 2;let n = arr.length;document.write("Indexes of zeroes to be flipped are ");findZeroes(arr, n, m);  // This code is contributed by Saurabh Jaiswal </script>
Indexes of zeroes to be flipped are 5 7 
Time Complexity: O(N) Auxiliary Space: O(1)
parashar
nitin mittal
Anuj Choudhury
rajatkesarwani
gfgking
Pankaj Kumar Gautam
umadevi9616
GauravRajput1
gulshankumarar231
simmytarika5
_shinchancode
hardikkoriintern
Accolite
Amazon
Arrays
Accolite
Amazon
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Introduction to Arrays
K'th Smallest/Largest Element in Unsorted Array | Set 1
Subset Sum Problem | DP-25
Introduction to Data Structures
Python | Using 2D arrays/lists the right way