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++
// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to get the number of
// 0s between two 1s
vector<int>
zBetweeno(string s,
vector<vector<int> >& queries)
{
// Store location of 1s
set<int> ones;
// Store number of candles before i
vector<int> one(s.size(), 0);
// Store result
vector<int> res;
// Storing number of candles before
// a specific position
// and locations of candles in a set
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];
}
// Iterating over queries
for (auto&& query : queries) {
// Get the location of first 1
int ss
= *ones.lower_bound(query[0]);
// Get the location of last 1
int ee
= s[query[1]] == '1'
? query[1]
: *--ones.lower_bound(query[1]);
// Check for corner cases
if (ss > query[1]
|| ee < query[0]) {
res.push_back(0);
continue;
}
int tot
= one[ee] - one[ss];
int loc = ee - ss;
// Storing result of the query
res.push_back(loc
- tot);
}
return res;
}
// Driver code
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.*;
// Java program for the above approach
class GFG{
// Function to get the number of
// 0s between two 1s
public static ArrayList<Integer> zBetweeno(String s, ArrayList<ArrayList<Integer>> queries)
{
// Store location of 1s
TreeSet<Integer> ones = new TreeSet<Integer>();
// Store number of candles before i
int one[] = new int[s.length()];
// Store result
ArrayList<Integer> res = new ArrayList<Integer>();
// Storing number of candles before
// a specific position
// and locations of candles in a set
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];
}
}
// Iterating over queries
for (int i = 0 ; i < queries.size() ; i++) {
ArrayList<Integer> query = queries.get(i);
// Get the location of first 1
int ss = ones.ceiling(query.get(0));
// Get the location of last 1
int ee = s.charAt(query.get(1)) == '1' ? query.get(1) : ones.floor(query.get(1)-1);
// Check for corner cases
if (ss > query.get(1) || ee < query.get(0)) {
res.add(0);
continue;
}
int tot = one[ee] - one[ss];
int loc = ee - ss;
// Storing result of the query
res.add(loc - tot);
}
return res;
}
// Driver code
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("");
}
}
// This code is contributed by subhamgoyal2014.
Python3
# Python 3 implementation of the above approach
from bisect import bisect_left
# Function to get the number of
# 0s between two 1s
def zBetweeno(s, queries):
# Store location of 1s
ones = set([])
# Store number of candles before i
one = [0]*len(s)
# Store result
res = []
# Storing number of candles before
# a specific position
# and locations of candles in a set
for i in range(len(s)):
if (s[i] == '1'):
ones.add(i)
one[i] += 1
if (i != 0):
one[i] += one[i - 1]
# Iterating over queries
for query in queries:
# Get the location of first 1
ss = bisect_left(list(ones), query[0])
# Get the location of last 1
if s[query[1]] == '1':
ee = query[1]
else:
ee = bisect_left(list(ones), query[1])
# Check for corner cases
if (ss > query[1]
or ee < query[0]):
res.append(0)
continue
tot = one[ee] - one[ss]
loc = ee - ss
# Storing result of the query
res.append(loc
- tot)
return res
# Driver code
if __name__ == "__main__":
queries = [[0, 4], [0, 5]]
input = "1001010"
res = zBetweeno(input, queries)
for elem in res:
print(elem, end=" ")
# This code is contributed by ukasp.
JavaScript
// JavaScript implementation of the approach
// Function to get the number of 0s between two 1s
function zBetweeno(s, queries) {
// Store location of 1s
const ones = new Set();
// Store number of candles before i
const one = Array(s.length).fill(0);
// Store result
const res = [];
// Storing number of candles before
// a specific position and locations of candles in a set
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];
}
}
// Iterating over queries
for (let query of queries) {
// Get the location of first 1
const ss = Array.from(ones).sort((a, b) => a - b).findIndex(x => x >= query[0]);
// Get the location of last 1
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]);
}
// Check for corner cases
if (ss > query[1] || ee < query[0]) {
res.push(0);
continue;
}
const tot = one[ee] - one[ss];
const loc = ee - ss;
// Storing result of the query
res.push(loc - tot);
}
return res;
}
const queries = [[0, 4], [0, 5]];
const input = "1001010";
const res = zBetweeno(input, queries);
console.log(res.join(" "));
//This code is contributed by Edula Vinay Kumar Reddy
C#
// C# equivalent of the above code
using System;
using System.Collections.Generic;
// C# program for the above approach
class GFG
{
// Function to get the number of
// 0s between two 1s
public static List<int> zBetweeno(string s, List<List<int>> queries)
{
// Store location of 1s
SortedSet<int> ones = new SortedSet<int>();
// Store number of candles before i
int[] one = new int[s.Length];
// Store result
List<int> res = new List<int>();
// Storing number of candles before
// a specific position
// and locations of candles in a set
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];
}
}
// Iterating over queries
for (int i = 0; i < queries.Count; i++)
{
List<int> query = queries[i];
// Get the location of first 1
int ss = ones.GetViewBetween(query[0], int.MaxValue).Min;
// Get the location of last 1
int ee = (s[query[1]] == '1') ? query[1] : ones.GetViewBetween(0, query[1] - 1).Max;
// Check for corner cases
if (ss > query[1] || ee < query[0])
{
res.Add(0);
continue;
}
int tot = one[ee] - one[ss];
int loc = ee - ss;
// Storing result of the query
res.Add(loc - tot);
}
return res;
}
// Driver code
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)
Similar Reads
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 3Explanation: The Queri
10 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
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
Count set bits in index range [L, R] in given Array for Q queries Given an array arr[] containing N integers and an array queries[] containing Q queries in the form of {L, R}, the task is to count the total number of set bits from L to R in array arr for each query. Example: Input: arr[]={1, 2, 3, 4, 5, 6}, queries[]={{0, 2}, {1, 1}, {3, 5}}Output:425Explanation:Q
6 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
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
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
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
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 0's between two immediate 1's in binary representation Given a number n, the task is to find the maximum 0's between two immediate 1's in binary representation of given n. Return -1 if binary representation contains less than two 1's. Examples : Input : n = 47 Output: 1 // binary of n = 47 is 101111 Input : n = 549 Output: 3 // binary of n = 549 is 1000
9 min read