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;
// 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
// 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 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#
// 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
JavaScript
<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>
Time Complexity: O(N + M)
Auxiliary Space: O(N)
Similar Reads
Maximum count of 0s between two 1s in given range for Q queries | Set - 2 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 3Explanation: The Querie
8 min read
Find element with maximum weight in given price range for Q queries Given an array arr[] of size N where each element denotes a pair in the form (price, weight) denoting the price and weight of each item. Given Q queries of the form [X, Y] denoting the price range. The task is to find the element with the highest weight within a given price range for each query. Exa
11 min read
Find the element having maximum set bits in the given range for Q queries Given an array arr[] of N integers and Q queries, each query having two integers L and R, the task is to find the element having maximum set bits in the range L to R. Note: If there are multiple elements having maximum set bits, then print the maximum of those. Examples: Input: arr[] = {18, 9, 8, 15
15+ min read
Count of Perfect Numbers in given range for Q queries Given an array arr[] consisting of N pairs, where each pair represents a query of the form {L, R}, the task is to find the count of perfect numbers in the given range for each query. Examples: Input: arr[][] = {{1, 10}, {10, 20}, {20, 30}}Output: 1 1 1Explanation: Query(1, 10): Perfect numbers in th
9 min read
Queries for the minimum element in an array excluding the given index range Given an array arr[] of N integers and Q queries where each query consists of an index range [L, R]. For each query, the task is to find the minimum element in the array excluding the elements from the given index range. Examples: Input: arr[] = {3, 2, 1, 4, 5}, Q[][] = {{1, 2}, {2, 3}} Output: 3 2
15+ min read
Maximum element in connected component of given node for Q queries Given an array of pairs arr[][] of length N, and an array queries[] of length M, and an integer R, where queries[i] contain an integer from 1 to R, the task for every queries[i] is to find the maximum element of the connected components of the node with value queries[i]. Note: Initially every intege
11 min read
Find the minimum range size that contains the given element for Q queries Given an array Intervals[] consisting of N pairs of integers where each pair is denoting the value range [L, R]. Also, given an integer array Q[] consisting of M queries. For each query, the task is to find the size of the smallest range that contains that element. Return -1 if no valid interval exi
12 min read
Range Queries to find the Element having Maximum Digit Sum Given an array Arr of N integers and Q queries, each query having a range from L to R. Find the element having maximum digit sum for the range L to R, and if more than one element has a maximum digit sum, then find the maximum element out of those. Examples: Input: Arr[] = { 16, 12, 43, 55} Q = 2 L
15+ min read
Minimum removals in range to make bitwise AND non-zero for given range queries Given an array queries[][] of Q range queries, the task is to find the minimum removals from the range[l, r] such that the bitwise AND of the range is a non-zero value. Examples: Input: queries[][] = { {1, 5}, {3, 4}, {5, 10}, {10, 15}}Output: 2 1 3 0 Explanation: Query-1: l = 1, r = 5 {1, 2, 3, 4,
14 min read
Maximum distance between two 1s in a Binary Array in a given range Given a binary array of size N and a range in [l, r], the task is to find the maximum distance between two 1s in this given range.Examples: Input: arr = {1, 0, 0, 1}, l = 0, r = 3 Output: 3 In the given range from 0 to 3, first 1 lies at index 0 and last at index 3. Hence, maximum distance = 3 - 0 =
14 min read