Maximum count of 0s between two 1s in given range for Q queries | Set – 2
Last Updated :
21 Feb, 2023
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 = “101”, Q[][] = {{0, 2}}
Output: 1
Approach: Another variation is already discussed in Set1 of this problem. Keep track of two entities: location of 1’s and the Number of 1’s that appeared before any specific position. Use a set to store the location of 1’s and an array to store the answer. Now to find the answer in range [i,j] use the following observation:
Let first and last 1s between given range is located at (i+first) and (i+last), then
Total 0’s between 1’s = total elements between these two locations – total 1’s between these to locations
= location difference between 1’s – (1’s appeared before (i+last) – 1’s appeared before (i+first) )
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int >
zBetweeno(string s,
vector<vector< int > >& queries)
{
set< int > ones;
vector< int > one(s.size(), 0);
vector< int > res;
for ( int i = 0; i < s.size(); i++) {
if (s[i] == '1' ) {
ones.insert(i);
one[i]++;
}
if (i != 0)
one[i] += one[i - 1];
}
for ( auto && query : queries) {
int ss
= *ones.lower_bound(query[0]);
int ee
= s[query[1]] == '1'
? query[1]
: *--ones.lower_bound(query[1]);
if (ss > query[1]
|| ee < query[0]) {
res.push_back(0);
continue ;
}
int tot
= one[ee] - one[ss];
int loc = ee - ss;
res.push_back(loc
- tot);
}
return res;
}
int main()
{
vector<vector< int > > queries
= { { 0, 4 }, { 0, 5 } };
string input = "1001010" ;
vector< int > res =
zBetweeno(input, queries);
for ( auto elem : res)
cout << elem << " " ;
cout << endl;
}
|
Java
import java.util.*;
import java.io.*;
class GFG{
public static ArrayList<Integer> zBetweeno(String s, ArrayList<ArrayList<Integer>> queries)
{
TreeSet<Integer> ones = new TreeSet<Integer>();
int one[] = new int [s.length()];
ArrayList<Integer> res = new ArrayList<Integer>();
for ( int i = 0 ; i < s.length() ; i++) {
if (s.charAt(i) == '1' ) {
ones.add(i);
one[i]++;
}
if (i != 0 ){
one[i] += one[i - 1 ];
}
}
for ( int i = 0 ; i < queries.size() ; i++) {
ArrayList<Integer> query = queries.get(i);
int ss = ones.ceiling(query.get( 0 ));
int ee = s.charAt(query.get( 1 )) == '1' ? query.get( 1 ) : ones.floor(query.get( 1 )- 1 );
if (ss > query.get( 1 ) || ee < query.get( 0 )) {
res.add( 0 );
continue ;
}
int tot = one[ee] - one[ss];
int loc = ee - ss;
res.add(loc - tot);
}
return res;
}
public static void main(String args[])
{
ArrayList<ArrayList<Integer> > queries = new ArrayList<>(
List.of(
new ArrayList<Integer>(
List.of( 0 , 4 )
),
new ArrayList<Integer>(
List.of( 0 , 5 )
)
)
);
String input = "1001010" ;
ArrayList<Integer> res = zBetweeno(input, queries);
for ( int i = 0 ; i < res.size() ; i++){
System.out.print(res.get(i) + " " );
}
System.out.println( "" );
}
}
|
Python3
from bisect import bisect_left
def zBetweeno(s, queries):
ones = set ([])
one = [ 0 ] * len (s)
res = []
for i in range ( len (s)):
if (s[i] = = '1' ):
ones.add(i)
one[i] + = 1
if (i ! = 0 ):
one[i] + = one[i - 1 ]
for query in queries:
ss = bisect_left( list (ones), query[ 0 ])
if s[query[ 1 ]] = = '1' :
ee = query[ 1 ]
else :
ee = bisect_left( list (ones), query[ 1 ])
if (ss > query[ 1 ]
or ee < query[ 0 ]):
res.append( 0 )
continue
tot = one[ee] - one[ss]
loc = ee - ss
res.append(loc
- tot)
return res
if __name__ = = "__main__" :
queries = [[ 0 , 4 ], [ 0 , 5 ]]
input = "1001010"
res = zBetweeno( input , queries)
for elem in res:
print (elem, end = " " )
|
Javascript
function zBetweeno(s, queries) {
const ones = new Set();
const one = Array(s.length).fill(0);
const res = [];
for (let i = 0; i < s.length; i++) {
if (s[i] === '1' ) {
ones.add(i);
one[i] += 1;
}
if (i !== 0) {
one[i] += one[i - 1];
}
}
for (let query of queries) {
const ss = Array.from(ones).sort((a, b) => a - b).findIndex(x => x >= query[0]);
let ee = 0;
if (s[query[1]] === '1' ) {
ee = query[1];
} else {
ee = Array.from(ones).sort((a, b) => a - b).findIndex(x => x > query[1]);
}
if (ss > query[1] || ee < query[0]) {
res.push(0);
continue ;
}
const tot = one[ee] - one[ss];
const loc = ee - ss;
res.push(loc - tot);
}
return res;
}
const queries = [[0, 4], [0, 5]];
const input = "1001010" ;
const res = zBetweeno(input, queries);
console.log(res.join( " " ));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public static List< int > zBetweeno( string s, List<List< int >> queries)
{
SortedSet< int > ones = new SortedSet< int >();
int [] one = new int [s.Length];
List< int > res = new List< int >();
for ( int i = 0; i < s.Length; i++)
{
if (s[i] == '1' )
{
ones.Add(i);
one[i]++;
}
if (i != 0)
{
one[i] += one[i - 1];
}
}
for ( int i = 0; i < queries.Count; i++)
{
List< int > query = queries[i];
int ss = ones.GetViewBetween(query[0], int .MaxValue).Min;
int ee = (s[query[1]] == '1' ) ? query[1] : ones.GetViewBetween(0, query[1] - 1).Max;
if (ss > query[1] || ee < query[0])
{
res.Add(0);
continue ;
}
int tot = one[ee] - one[ss];
int loc = ee - ss;
res.Add(loc - tot);
}
return res;
}
public static void Main( string [] args)
{
List<List< int >> queries = new List<List< int >>()
{
new List< int > { 0, 4 },
new List< int > { 0, 5 }
};
string input = "1001010" ;
List< int > res = zBetweeno(input, queries);
foreach ( int i in res)
Console.Write(i + " " );
}
}
|
Time Complexity: O(N*logN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...