Maximum count of 0s between two 1s in given range for Q queries
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:
- 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”.
- 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 <iostream>
using namespace std;
void countOsBetween1s(string S, int N, int Q[][2])
{
int leftBound[N];
int rightBound[N];
int count = 0;
int total = 0;
for ( int i = 0; i < N; i++) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
rightBound[i] = count;
}
count = 0;
total = 0;
for ( int i = N - 1; i >= 0; i--) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
leftBound[i] = count;
}
for ( int q = 0; q < 2; q++) {
int L = Q[q][0];
int R = Q[q][1];
count = leftBound[L] + rightBound[R] - total;
cout << count << " " ;
}
}
int main()
{
string S = "1001010" ;
int Q[][2] = { { 0, 4 }, { 0, 5 } };
int N = S.length();
countOsBetween1s(S, N, Q);
return 0;
}
|
Java
import java.lang.*;
import java.util.*;
class GFG {
static void countOsBetween1s(
String S, int N, int [][] Q)
{
int [] leftBound = new int [N];
int [] rightBound = new int [N];
int count = 0 ;
int total = 0 ;
for ( int i = 0 ; i < N; i++) {
if (S.charAt(i) == '1' ) {
count = total;
}
else if (S.charAt(i) == '0' ) {
total++;
}
rightBound[i] = count;
}
count = 0 ;
total = 0 ;
for ( int i = N - 1 ; i >= 0 ; i--) {
if (S.charAt(i) == '1' ) {
count = total;
}
else if (S.charAt(i) == '0' ) {
total++;
}
leftBound[i] = count;
}
for ( int q = 0 ; q < Q.length; q++) {
int L = Q[q][ 0 ];
int R = Q[q][ 1 ];
count = leftBound[L] + rightBound[R] - total;
System.out.print(count + " " );
}
}
public static void main(String[] args)
{
String S = "1001010" ;
int Q[][] = { { 0 , 4 }, { 0 , 5 } };
int N = S.length();
countOsBetween1s(S, N, Q);
}
}
|
Python3
def countOsBetween1s(S, N, Q):
leftBound = [ 0 ] * N
rightBound = [ 0 ] * N
count = 0
total = 0
for i in range (N):
if (S[i] = = '1' ):
count = total
elif (S[i] = = '0' ):
total + = 1
rightBound[i] = count
count = 0
total = 0
for i in range (N - 1 , - 1 , - 1 ):
if (S[i] = = '1' ):
count = total
elif (S[i] = = '0' ):
total + = 1
leftBound[i] = count
for q in range ( 2 ):
L = Q[q][ 0 ]
R = Q[q][ 1 ]
count = leftBound[L] + rightBound[R] - total
print (count, end = " " )
if __name__ = = "__main__" :
S = "1001010"
Q = [[ 0 , 4 ], [ 0 , 5 ]]
N = len (S)
countOsBetween1s(S, N, Q)
|
C#
using System;
public class GFG {
static void countOsBetween1s(
String S, int N, int [,] Q)
{
int [] leftBound = new int [N];
int [] rightBound = new int [N];
int count = 0;
int total = 0;
for ( int i = 0; i < N; i++) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
rightBound[i] = count;
}
count = 0;
total = 0;
for ( int i = N - 1; i >= 0; i--) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
leftBound[i] = count;
}
for ( int q = 0; q < Q.GetLength(0); q++) {
int L = Q[q,0];
int R = Q[q,1];
count = leftBound[L] + rightBound[R] - total;
Console.Write(count + " " );
}
}
public static void Main(String[] args)
{
String S = "1001010" ;
int [,]Q = { { 0, 4 }, { 0, 5 } };
int N = S.Length;
countOsBetween1s(S, N, Q);
}
}
|
Javascript
<script>
function countOsBetween1s(S, N, Q) {
let leftBound = new Array(N);
let rightBound = new Array(N);
let count = 0;
let total = 0;
for (let i = 0; i < N; i++) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
rightBound[i] = count;
}
count = 0;
total = 0;
for (let i = N - 1; i >= 0; i--) {
if (S[i] == '1' ) {
count = total;
}
else if (S[i] == '0' ) {
total++;
}
leftBound[i] = count;
}
for (let q = 0; q < 2; q++) {
let L = Q[q][0];
let R = Q[q][1];
count = leftBound[L] + rightBound[R] - total;
document.write(count + " " );
}
}
let S = "1001010" ;
let Q = [[0, 4], [0, 5]];
let N = S.length;
countOsBetween1s(S, N, Q);
</script>
|
Time Complexity: O(N + M)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...