Count of substrings whose Decimal equivalent is greater than or equal to K
Last Updated :
31 Aug, 2023
Given an integer K and a binary string S of length N, the task is to find out the number of substrings whose decimal equivalent is greater than or equal to K.
Examples:
Input: K = 3, S = “11100”
Output: 8
Explanation:
There are 8 such substring whose decimal equivalent is greater than or equal to 3, as mentioned below:
Substring – Decimal Equivalent
“100” – 4,
“1100” – 12,
“11100” – 28,
“110” – 6,
“1110” – 14,
“11” – 3,
“111” – 7,
“11” – 3
Input: K = 5, S = “10110110”
Output: 19
Explanation:
There are 19 such substring whose decimal equivalent is greater than or equal to 5.
Naive Approach: Find out all the substrings and for each substring, convert it from binary to decimal and check if it is greater than or equal to K. Count the number of every such substring found.
Efficient Approach: Using the Two-Pointer technique
- The idea is to maintain two-pointers L and R.
- Fix the position of the right pointer ‘R’ of the substring to length – 1 and iterate with a loop until the value of R is positive:
- Initialize the value of L to R, for considering the substring of length 1
- Decrement the value of L by 1 until the decimal equivalent of the substring of length R – L + 1 is greater than or equal to K
- Increment the counter by the number of bits on the left of the L.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
unsigned long long countSubstr(
string& s, int k)
{
int n = s.length();
int l = n - 1;
int r = n - 1;
int arr[n];
int last_indexof1 = -1;
for ( int i = 0; i < n; i++) {
if (s[i] == '1' ) {
arr[i] = i;
last_indexof1 = i;
}
else {
arr[i] = last_indexof1;
}
}
unsigned long long no_of_substr = 0;
for (r = n - 1; r >= 0; r--) {
l = r;
while (l >= 0
&& (r - l + 1) <= 64
&& stoull(
s.substr(l, r - l + 1), 0, 2)
< k) {
l--;
}
if (r - l + 1 <= 64)
no_of_substr += l + 1;
else {
no_of_substr += arr[l + 1] + 1;
}
}
return no_of_substr;
}
int main()
{
string s = "11100" ;
unsigned long long int k = 3;
cout << countSubstr(s, k);
}
|
Java
import java.util.*;
class GFG{
static long countSubstr(
String s, int k)
{
int n = s.length();
int l = n - 1 ;
int r = n - 1 ;
int []arr = new int [n];
int last_indexof1 = - 1 ;
for ( int i = 0 ; i < n; i++) {
if (s.charAt(i) == '1' ) {
arr[i] = i;
last_indexof1 = i;
}
else {
arr[i] = last_indexof1;
}
}
long no_of_substr = 0 ;
for (r = n - 1 ; r >= 0 ; r--) {
l = r;
while (l >= 0
&& (r - l + 1 ) <= 64
&& Integer.valueOf(s.substring(l, r + 1 ), 2 )
< k) {
l--;
}
if (r - l + 1 <= 64 )
no_of_substr += l + 1 ;
else {
no_of_substr += arr[l + 1 ] + 1 ;
}
}
return no_of_substr;
}
public static void main(String[] args)
{
String s = "11100" ;
int k = 3 ;
System.out.println(countSubstr(s, k));
}
}
|
Python3
def countSubstr(s, k):
n = len (s)
l = n - 1
r = n - 1
arr = [ 0 ] * n
last_indexof1 = - 1
for i in range (n):
if (s[i] = = '1' ):
arr[i] = i
last_indexof1 = i
else :
arr[i] = last_indexof1
no_of_substr = 0
for r in range (n - 1 , - 1 , - 1 ):
l = r
while (l > = 0 and (r - l + 1 ) < = 64 and int (s[l:r + 1 ], 2 )< k):
l - = 1
if (r - l + 1 < = 64 ):
no_of_substr + = l + 1
else :
no_of_substr + = arr[l + 1 ] + 1
return no_of_substr
s = "11100"
k = 3
print (countSubstr(s, k))
|
C#
using System;
class GFG{
static long countSubstr(
String s, int k)
{
int n = s.Length;
int l = n - 1;
int r = n - 1;
int []arr = new int [n];
int last_indexof1 = -1;
for ( int i = 0; i < n; i++) {
if (s[i] == '1' ) {
arr[i] = i;
last_indexof1 = i;
}
else {
arr[i] = last_indexof1;
}
}
long no_of_substr = 0;
for (r = n - 1; r >= 0; r--) {
l = r;
while (l >= 0
&& (r - l + 1) <= 64 && ( int )(Convert.ToInt32(s.Substring(l, r + 1-l), 2))
< k) {
l--;
}
if (r - l + 1 <= 64)
no_of_substr += l + 1;
else {
no_of_substr += arr[l + 1] + 1;
}
}
return no_of_substr;
}
public static void Main(String[] args)
{
String s = "11100" ;
int k = 3;
Console.WriteLine(countSubstr(s, k));
}
}
|
Javascript
<script>
function countSubstr(s,k)
{
let n = s.length;
let l = n - 1;
let r = n - 1;
let arr = new Array(n);
let last_indexof1 = -1;
for (let i = 0; i < n; i++) {
if (s[i] == '1' ) {
arr[i] = i;
last_indexof1 = i;
}
else {
arr[i] = last_indexof1;
}
}
let no_of_substr = 0;
for (r = n - 1; r >= 0; r--) {
l = r;
while (l >= 0
&& (r - l + 1) <= 64
&& parseInt(s.substring(l, r + 1),2)
< k) {
l--;
}
if (r - l + 1 <= 64)
no_of_substr += l + 1;
else {
no_of_substr += arr[l + 1] + 1;
}
}
return no_of_substr;
}
let s = "11100" ;
let k = 3;
document.write(countSubstr(s, k));
</script>
|
Time Complexity: O(n2), where n is the length of the given string.
Auxiliary Space: O(n)
Efficient Approach:Using Prefix Sum
In this approach we first compute the decimal value of each substring using a prefix sum array. Then we loop through all potential substrings, checking to see if their decimal value is higher than or equal to K. If it is, we add one to the answer.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int count_Substr(string S, int K)
{
int N = S.length();
vector< int > prefix_sum(N, 0);
prefix_sum[0] = S[0] - '0' ;
for ( int i = 1; i < N; i++) {
prefix_sum[i] = prefix_sum[i-1] * 2 + (S[i] - '0' );
}
int ans = 0;
for ( int i = 0; i < N; i++) {
for ( int j = i; j < N; j++) {
int decimal_value = prefix_sum[j];
if (i > 0) {
decimal_value -= prefix_sum[i-1] * (1 << (j-i+1));
}
if (decimal_value >= K) {
ans++;
}
}
}
return ans;
}
int main()
{
string S = "11100" ;
int K= 3;
cout << count_Substr(S,K)<<endl;
}
|
Java
import java.util.*;
public class GFG {
public static int countSubstr(String S, int K) {
int N = S.length();
int [] prefixSum = new int [N];
prefixSum[ 0 ] = S.charAt( 0 ) - '0' ;
for ( int i = 1 ; i < N; i++) {
prefixSum[i] = prefixSum[i - 1 ] * 2 + (S.charAt(i) - '0' );
}
int count = 0 ;
for ( int i = 0 ; i < N; i++) {
for ( int j = i; j < N; j++) {
int decimalValue = prefixSum[j];
if (i > 0 ) {
decimalValue -= prefixSum[i - 1 ] * ( 1 << (j - i + 1 ));
}
if (decimalValue >= K) {
count++;
}
}
}
return count;
}
public static void main(String[] args) {
String S = "11100" ;
int K = 3 ;
System.out.println(countSubstr(S, K));
}
}
|
Python3
def count_Substr(S, K):
N = len (S)
prefix_sum = [ 0 ] * N
prefix_sum[ 0 ] = int (S[ 0 ])
for i in range ( 1 , N):
prefix_sum[i] = prefix_sum[i - 1 ] * 2 + int (S[i])
ans = 0
for i in range (N):
for j in range (i, N):
decimal_value = prefix_sum[j]
if i > 0 :
decimal_value - = prefix_sum[i - 1 ] * ( 1 << (j - i + 1 ))
if decimal_value > = K:
ans + = 1
return ans
S = "11100"
K = 3
print (count_Substr(S, K))
|
C#
using System;
class GFG
{
static int CountSubstr( string S, int K)
{
int N = S.Length;
int [] prefixSum = new int [N];
prefixSum[0] = S[0] - '0' ;
for ( int i = 1; i < N; i++)
{
prefixSum[i] = prefixSum[i - 1] * 2 + (S[i] - '0' );
}
int ans = 0;
for ( int i = 0; i < N; i++)
{
for ( int j = i; j < N; j++)
{
int decimalValue = prefixSum[j];
if (i > 0)
{
decimalValue -= prefixSum[i - 1] * (1 << (j - i + 1));
}
if (decimalValue >= K)
{
ans++;
}
}
}
return ans;
}
static void Main()
{
string S = "11100" ;
int K = 3;
Console.WriteLine(CountSubstr(S, K));
}
}
|
Javascript
function countSubstr(S, K) {
const N = S.length;
const prefixSum = new Array(N);
prefixSum[0] = parseInt(S.charAt(0));
for (let i = 1; i < N; i++) {
prefixSum[i] = prefixSum[i - 1] * 2 + parseInt(S.charAt(i));
}
let count = 0;
for (let i = 0; i < N; i++) {
for (let j = i; j < N; j++) {
let decimalValue = prefixSum[j];
if (i > 0) {
decimalValue -= prefixSum[i - 1] * (1 << (j - i + 1));
}
if (decimalValue >= K) {
count++;
}
}
}
return count;
}
const S = "11100" ;
const K = 3;
console.log(countSubstr(S, K));
|
Output:
8
Time Complexity: O(n*logn), where n is the length of the given string.
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...