
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Maximum Count of 0s Between Two 1s for Q Queries
A binary string is a string that only contains the zeroes and ones as the different characters in them. We are given a binary string and an array of a given length that will contain the pairs. Each pair defines the range, and in that range, we have to return the maximum number of zeros lying between two ones. We will implement two approaches one is the naive approach and another is the efficient approach.
Let's understand with the help of example
Input
String str = ?1011010110'
Array Q[][] = {{0,2}, {2,5}, {0,9}}
Output: 1 1 3
Explanation ? For the range 0 to 2, we have only 1 zero between the one present at the 0th and 2nd index. For the range of 2 to 5, again we have only 1 zero present between the one present at the 2nd and 5th index or the 3rd and 5th index.
For the last query, we have three zeros present between the 0th index and both the 7th and 8th index.
Naive Approach
In this approach, we will travel for each query and will manage the count of zeros from the first one tackled in the range to the last one. If any of the side ones does not occur then in that case answer is zero.
We will traverse the string for each query and will check in the given range for the number of zeroes.
We will use a flag to mark if there is at least one present in range and if one is present then will mark the flag and start counting the zeroes from there, and if it again any character 1 appears we will store the number of zeros in the flag variable as it will always be maximum in that range.
Also, to mark the number of zeroes we will maintain a variable.
Let us see the code ?
Example
#include <bits/stdc++.h> using namespace std; // function to find the zeroes in the range int zeroesInRange(int l, int r, string str){ // checking for the current range int flag = -1; // flag to indicate the whether one is present on first side or not int count = 0; for(int i = l; i <= r; i++){ if(str[i] == '1'){ if(flag == -1){ flag = 0; count = 0; } else{ flag = count; } } else{ count++; } } if(flag == -1){ return 0; } else{ return flag; } } int main(){ string str = "1010110110"; int Q[][2] = {{0,2}, {2,5}, {0,9}}; int m = 3; // size of the queries // traversing over the array for(int i=0; i<m; i++){ // calling the function cout<<zeroesInRange(Q[i][0], Q[i][1], str)<<" "; } cout<<endl; return 0; }
Output
1 1 3
Time and Space Complexity
The time complexity of the above code is O(Q*N) where Q is the size of the query array and N is the size of the string.
The space complexity of the above code O(1), as we are not using any extra space here.
Efficient Approach
In the previous approach, we were traversing over the array for each query making the time complexity non-linear. We will use the concept of the pre-fix array and will store the results initially to get the answer in O(1) instead of O(N) for each query.
We will store the index of the ones present to the left and right of the current index and prefix sum of the number of zeros.
For the current range we will find the right one of the left range element and rightmost one of the right range element and for them we will find the number of zeroes lying in between of them. Let us see the code ?
Example
#include <bits/stdc++.h> using namespace std; // function to solve the queries void findQueries(int Q[][2], string str, int m){ int n = str.length(); // getting the length of the string // defining the vectors to store the find the one present // nearest on the both left and the right side // also, to store the prefix zeroes vector<int> leftOne(n), rightOne(n), preZero(n); int lastOne = -1; // variable to store the last one // traversing over the array to get the left One for(int i=0; i<n; i++){ if(str[i] == '1'){ lastOne = i; } leftOne[i] = lastOne; } lastOne = n; // traversing over the array to get the right One for(int i=n-1; i>=0 ;i--){ if(str[i] == '1'){ lastOne = i; } rightOne[i] = lastOne; } // traversing over the array to get the prefix value of zeros for(int i=0; i<n; i++){ if(str[i] == '0'){ preZero[i]++; } if(i != 0){ preZero[i] += preZero[i-1]; } } // traversing over the queries array for(int i=0; i<m; i++){ int l = rightOne[Q[i][0]]; int r = leftOne[Q[i][1]]; if(l >= r){ cout<<0<<" "; } else{ if(l == 0){ cout<<preZero[r]<<" "; } else{ cout<<preZero[r]-preZero[l]<<" "; } } } cout<<endl; } int main(){ string str = "1010110110"; int Q[][2] = {{0,2}, {2,5}, {0,9}}; int m = 3; // size of the queries // calling to the function findQueries(Q, str, m); return 0; }
Output
1 1 3
Time and Space Complexity
The time complexity of the above code is O(max(Q,N)), where Q is the number of queries and N is the length of the string.
The space complexity of the above code is O(N) because we are storing the elements in the vector.
Conclusion
In this tutorial, we have implemented a code to find the solution to queries to find the number of zeros present in between two ones of the given binary string. We have implemented two codes one is with the time complexity of O(N*Q) with constant space and another with the O(N) time complexity and O(N) space complexity.