Open In App

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

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:

Below is the implementation of the above approach:




#include <iostream>
using namespace std;
 
// Function to count the number of
// 0s lying between the two 1s for
// each query
void 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 Code
int 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 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);
    }
}




# Function to count the number of
# 0s lying between the two 1s for
# each query
def 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 Code
if __name__ == "__main__":
 
    S = "1001010"
    Q = [[0, 4], [0, 5]]
    N = len(S)
    countOsBetween1s(S, N, Q)
 
    # This code is contributed by ukasp.




// C# program for the above approach
using 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




<script>
 
// Function to count the number of
// 0s lying between the two 1s for
// each query
function countOsBetween1s(S, N, Q) {
 
    // Stores count of 0's that are
    // right to the most recent 1's
    let leftBound = new Array(N);
 
    // Stores count of 0's that are
    // left to the most recent 1's
    let rightBound = new Array(N);
 
    // Stores the count of zeros
    // in a prefix/suffix of array
    let count = 0;
 
    // Stores the count of total 0s
    let total = 0;
 
    // Traverse the string S
    for (let 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 (let 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 (let q = 0; q < 2; q++) {
 
        let L = Q[q][0];
        let 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]
        document.write(count + " ");
    }
}
 
// Driver Code
 
let S = "1001010";
let Q = [[0, 4], [0, 5]];
let N = S.length;
countOsBetween1s(S, N, Q);
 
 
// This code is contributed by gfgking
</script>

Output: 
2 3

 

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


Article Tags :