# Maximum count of 0s between two 1s in given range for Q queries

• Difficulty Level : Medium
• Last Updated : 31 Aug, 2021

Given a binary string S of size N, and a 2D array Q[][] of queries consisting of M pairs of the form {L, R}, the task for each query is to find the maximum number of 0s lying between two 1s in the range [L, R].

Examples:

Input: S = “1001010”, Q[][] = {{0, 4}, {0, 5}}
Output: 2 3
Explanation:
The Queries are performed as per the following:

1. Query(0, 4): Print 2 as there are maximum 2 0’s lying between the indices 0 and 3 in the substring over the range [0, 4] i.e., “10010”.
2. Query(0, 5): Print 3 as there are maximum 3 0’s lying between the indices 0 and 5 in the substring over the range [0, 5] i.e “100101”.

Input: S = “111”, Q[][] = {{0, 2}}
Output: 0

Naive Approach: The simplest approach to solve the given problem is to traverse the given array of queries Q[][] and for each query print the maximum number of 0s between any two pair of 1s by iterating over the range [L, R].

Time Complexity: O(N*M)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized using the concept of Prefix Sum Array which will result in the constant time calculation of a query. Follow the steps below to solve the problem:

• Initialize two arrays say leftBound[] and rightBound[] to stores the count of 0s that are right to the most recent 1s and the count of 0s that are left to the most recent 1s respectively.
• Initialize two variables, say count and total to update the arrays leftBound[] and rightBound[].
• Traverse the given string S and if the current character is ‘1‘ then assign the value of curr to the variable total. Otherwise, increment totals by 1 and then assign the value of curr to the rightBound[i].
• Update the value of curr and totals to 0.
• Traverse the string in the reverse order and in each iteration if the current character is ‘1‘ then update the value of curr to the total. Otherwise, increment the value of total by 1 and then update the value of curr to the lefttBound[i].
• After completing the above steps, traverse the given array of queries Q[][] and for each query print the value of (leftBound[Q[i][0]] + rightBound[Q[i][1]] – total) as the resultant maximum number of 0s.

Below is the implementation of the above approach:

## C++

 #include using namespace std; // Function to count the number of// 0s lying between the two 1s for// each queryvoid countOsBetween1s(string S, int N, int Q[][2]){     // Stores count of 0's that are    // right to the most recent 1's    int leftBound[N];     // Stores count of 0's that are    // left to the most recent 1's    int rightBound[N];     // Stores the count of zeros    // in a prefix/suffix of array    int count = 0;     // Stores the count of total 0s    int total = 0;     // Traverse the string S    for (int i = 0; i < N; i++) {         // If current character is        // '1'        if (S[i] == '1') {            count = total;        }         // Otherwise        else if (S[i] == '0') {            total++;        }         // Update the rightBound[i]        rightBound[i] = count;    }     // Update count and total to 0    count = 0;    total = 0;     // Traverse the string S in    // reverse manner    for (int i = N - 1; i >= 0; i--) {         // If current character is        // '1'        if (S[i] == '1') {            count = total;        }         // Otherwise        else if (S[i] == '0') {            total++;        }         // Update the leftBound[i]        leftBound[i] = count;    }     // Traverse given query array    for (int q = 0; q < 2; q++) {         int L = Q[q][0];        int R = Q[q][1];         // Update the value of count        count = leftBound[L] + rightBound[R] - total;         // Print the count as the        // result to the current        // query [L, R]        cout << count << " ";    }} // Driver Codeint main(){     string S = "1001010";    int Q[][2] = { { 0, 4 }, { 0, 5 } };    int N = S.length();    countOsBetween1s(S, N, Q);    return 0;} // This code is contributed by Potta Lokesh

## Java

 // Java program for the above approach import java.lang.*;import java.util.*; class GFG {     // Function to count the number of    // 0s lying between the two 1s for    // each query    static void countOsBetween1s(        String S, int N, int[][] Q)    {         // Stores count of 0's that are        // right to the most recent 1's        int[] leftBound = new int[N];         // Stores count of 0's that are        // left to the most recent 1's        int[] rightBound = new int[N];         // Stores the count of zeros        // in a prefix/suffix of array        int count = 0;         // Stores the count of total 0s        int total = 0;         // Traverse the string S        for (int i = 0; i < N; i++) {             // If current character is            // '1'            if (S.charAt(i) == '1') {                count = total;            }             // Otherwise            else if (S.charAt(i) == '0') {                total++;            }             // Update the rightBound[i]            rightBound[i] = count;        }         // Update count and total to 0        count = 0;        total = 0;         // Traverse the string S in        // reverse manner        for (int i = N - 1; i >= 0; i--) {             // If current character is            // '1'            if (S.charAt(i) == '1') {                count = total;            }             // Otherwise            else if (S.charAt(i) == '0') {                total++;            }             // Update the leftBound[i]            leftBound[i] = count;        }         // Traverse given query array        for (int q = 0; q < Q.length; q++) {             int L = Q[q][0];            int R = Q[q][1];             // Update the value of count            count = leftBound[L] + rightBound[R] - total;             // Print the count as the            // result to the current            // query [L, R]            System.out.print(count + " ");        }    }     // Driver Code    public static void main(String[] args)    {        String S = "1001010";        int Q[][] = { { 0, 4 }, { 0, 5 } };        int N = S.length();        countOsBetween1s(S, N, Q);    }}

## Python3

 # Function to count the number of# 0s lying between the two 1s for# each querydef countOsBetween1s(S, N, Q):     # Stores count of 0's that are    # right to the most recent 1's    leftBound = [0]*N     # Stores count of 0's that are    # left to the most recent 1's    rightBound = [0]*N     # Stores the count of zeros    # in a prefix/suffix of array    count = 0     # Stores the count of total 0s    total = 0     # Traverse the string S    for i in range(N):         # If current character is        # '1'        if (S[i] == '1'):            count = total         # Otherwise        elif (S[i] == '0'):            total += 1         # Update the rightBound[i]        rightBound[i] = count     # Update count and total to 0    count = 0    total = 0     # Traverse the string S in    # reverse manner    for i in range(N - 1, -1, -1):         # If current character is        # '1'        if (S[i] == '1'):            count = total         # Otherwise        elif (S[i] == '0'):            total += 1         # Update the leftBound[i]        leftBound[i] = count     # Traverse given query array    for q in range(2):         L = Q[q][0]        R = Q[q][1]         # Update the value of count        count = leftBound[L] + rightBound[R] - total         # Print the count as the        # result to the current        # query [L, R]        print(count, end=" ")  # Driver Codeif __name__ == "__main__":     S = "1001010"    Q = [[0, 4], [0, 5]]    N = len(S)    countOsBetween1s(S, N, Q)     # This code is contributed by ukasp.

## C#

 // C# program for the above approachusing System; public class GFG {     // Function to count the number of    // 0s lying between the two 1s for    // each query    static void countOsBetween1s(        String S, int N, int[,] Q)    {         // Stores count of 0's that are        // right to the most recent 1's        int[] leftBound = new int[N];         // Stores count of 0's that are        // left to the most recent 1's        int[] rightBound = new int[N];         // Stores the count of zeros        // in a prefix/suffix of array        int count = 0;         // Stores the count of total 0s        int total = 0;         // Traverse the string S        for (int i = 0; i < N; i++) {             // If current character is            // '1'            if (S[i] == '1') {                count = total;            }             // Otherwise            else if (S[i] == '0') {                total++;            }             // Update the rightBound[i]            rightBound[i] = count;        }         // Update count and total to 0        count = 0;        total = 0;         // Traverse the string S in        // reverse manner        for (int i = N - 1; i >= 0; i--) {             // If current character is            // '1'            if (S[i] == '1') {                count = total;            }             // Otherwise            else if (S[i] == '0') {                total++;            }             // Update the leftBound[i]            leftBound[i] = count;        }         // Traverse given query array        for (int q = 0; q < Q.GetLength(0); q++) {             int L = Q[q,0];            int R = Q[q,1];             // Update the value of count            count = leftBound[L] + rightBound[R] - total;             // Print the count as the            // result to the current            // query [L, R]            Console.Write(count + " ");        }    }     // Driver Code    public static void Main(String[] args)    {        String S = "1001010";        int [,]Q = { { 0, 4 }, { 0, 5 } };        int N = S.Length;        countOsBetween1s(S, N, Q);    }} // This code is contributed by Amit Katiyar

## Javascript



Output:

2 3

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

My Personal Notes arrow_drop_up