Open In App

Count of substrings whose Decimal equivalent is greater than or equal to K

Last Updated : 31 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:
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  

  1. The idea is to maintain two-pointers L and R.
  2. 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++




// C++ implementation to count the
// substrings whose decimal equivalent
// is greater than or equal to K
#include <bits/stdc++.h>
using namespace std;
 
// Function to count number of
// substring whose decimal equivalent
// is greater than or equal to K
unsigned long long countSubstr(
    string& s, int k)
{
 
    int n = s.length();
 
    // Left pointer of the substring
    int l = n - 1;
 
    // Right pointer of the substring
    int r = n - 1;
    int arr[n];
    int last_indexof1 = -1;
 
    // Loop to maintain the last
    // occurrence of the 1 in the string
    for (int i = 0; i < n; i++) {
        if (s[i] == '1') {
            arr[i] = i;
            last_indexof1 = i;
        }
        else {
            arr[i] = last_indexof1;
        }
    }
 
    // Variable to count the substring
    unsigned long long no_of_substr = 0;
 
    // Loop to maintain the every
    // possible end index of the substring
    for (r = n - 1; r >= 0; r--) {
        l = r;
 
        // Loop to find the substring
        // whose decimal equivalent is
        // greater than or equal to K
        while (l >= 0
               && (r - l + 1) <= 64
               && stoull(
                      s.substr(l, r - l + 1), 0, 2)
                      < k) {
            l--;
        }
 
        // Condition to check no
        // of bits is out of bound
        if (r - l + 1 <= 64)
            no_of_substr += l + 1;
        else {
            no_of_substr += arr[l + 1] + 1;
        }
    }
    return no_of_substr;
}
 
// Driver Code
int main()
{
    string s = "11100";
    unsigned long long int k = 3;
    cout << countSubstr(s, k);
}


Java




// Java implementation to count the
// subStrings whose decimal equivalent
// is greater than or equal to K
import java.util.*;
 
class GFG{
  
// Function to count number of
// subString whose decimal equivalent
// is greater than or equal to K
static long countSubstr(
    String s, int k)
{
  
    int n = s.length();
  
    // Left pointer of the subString
    int l = n - 1;
  
    // Right pointer of the subString
    int r = n - 1;
    int []arr = new int[n];
    int last_indexof1 = -1;
  
    // Loop to maintain the last
    // occurrence of the 1 in the String
    for (int i = 0; i < n; i++) {
        if (s.charAt(i) == '1') {
            arr[i] = i;
            last_indexof1 = i;
        }
        else {
            arr[i] = last_indexof1;
        }
    }
  
    // Variable to count the subString
    long no_of_substr = 0;
  
    // Loop to maintain the every
    // possible end index of the subString
    for (r = n - 1; r >= 0; r--) {
        l = r;
  
        // Loop to find the subString
        // whose decimal equivalent is
        // greater than or equal to K
        while (l >= 0
               && (r - l + 1) <= 64
               && Integer.valueOf(s.substring(l, r + 1),2)
                      < k) {
            l--;
        }
  
        // Condition to check no
        // of bits is out of bound
        if (r - l + 1 <= 64)
            no_of_substr += l + 1;
        else {
            no_of_substr += arr[l + 1] + 1;
        }
    }
    return no_of_substr;
}
  
// Driver Code
public static void main(String[] args)
{
    String s = "11100";
    int k = 3;
    System.out.println(countSubstr(s, k));
}
}
 
// This code is contributed by PrinciRaj1992


Python3




# Python3 implementation to count the
# substrings whose decimal equivalent
# is greater than or equal to K
 
# Function to count number of
# substring whose decimal equivalent
# is greater than or equal to K
def countSubstr(s, k):
 
    n = len(s)
 
    # Left pointer of the substring
    l = n - 1
 
    # Right pointer of the substring
    r = n - 1
    arr = [0]*n
    last_indexof1 = -1
 
    # Loop to maintain the last
    # occurrence of the 1 in the string
    for i in range(n):
        if (s[i] == '1'):
            arr[i] = i
            last_indexof1 = i
 
        else:
            arr[i] = last_indexof1
 
    # Variable to count the substring
    no_of_substr = 0
 
    # Loop to maintain the every
    # possible end index of the substring
    for r in range(n - 1, -1, -1):
        l = r
 
        # Loop to find the substring
        # whose decimal equivalent is
        # greater than or equal to K
        while (l >= 0 and (r - l + 1) <= 64 and int(s[l:r + 1], 2)< k):
            l -= 1
 
        # Condition to check no
        # of bits is out of bound
        if (r - l + 1 <= 64):
            no_of_substr += l + 1
        else:
            no_of_substr += arr[l + 1] + 1
 
    return no_of_substr
 
# Driver Code
 
s = "11100"
k = 3
print(countSubstr(s, k))
 
# This code is contributed by mohit kumar 29


C#




// C# implementation to count the
// subStrings whose decimal equivalent
// is greater than or equal to K
using System;
 
class GFG{
   
// Function to count number of
// subString whose decimal equivalent
// is greater than or equal to K
static long countSubstr(
    String s, int k)
{
   
    int n = s.Length;
   
    // Left pointer of the subString
    int l = n - 1;
   
    // Right pointer of the subString
    int r = n - 1;
    int []arr = new int[n];
    int last_indexof1 = -1;
   
    // Loop to maintain the last
    // occurrence of the 1 in the String
    for (int i = 0; i < n; i++) {
        if (s[i] == '1') {
            arr[i] = i;
            last_indexof1 = i;
        }
        else {
            arr[i] = last_indexof1;
        }
    }
   
    // Variable to count the subString
    long no_of_substr = 0;
   
    // Loop to maintain the every
    // possible end index of the subString
    for (r = n - 1; r >= 0; r--) {
        l = r;
   
        // Loop to find the subString
        // whose decimal equivalent is
        // greater than or equal to K
        while (l >= 0
               && (r - l + 1) <= 64 && (int)(Convert.ToInt32(s.Substring(l, r + 1-l), 2))
                      < k) {
            l--;
        }
   
        // Condition to check no
        // of bits is out of bound
        if (r - l + 1 <= 64)
            no_of_substr += l + 1;
        else {
            no_of_substr += arr[l + 1] + 1;
        }
    }
    return no_of_substr;
}
   
// Driver Code
public static void Main(String[] args)
{
    String s = "11100";
    int k = 3;
    Console.WriteLine(countSubstr(s, k));
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
// Javascript implementation to count the
// subStrings whose decimal equivalent
// is greater than or equal to K
 
// Function to count number of
// subString whose decimal equivalent
// is greater than or equal to K
function countSubstr(s,k)
{
    let n = s.length;
    
    // Left pointer of the subString
    let l = n - 1;
    
    // Right pointer of the subString
    let r = n - 1;
    let arr = new Array(n);
    let last_indexof1 = -1;
    
    // Loop to maintain the last
    // occurrence of the 1 in the String
    for (let i = 0; i < n; i++) {
        if (s[i] == '1') {
            arr[i] = i;
            last_indexof1 = i;
        }
        else {
            arr[i] = last_indexof1;
        }
    }
    
    // Variable to count the subString
    let no_of_substr = 0;
    
    // Loop to maintain the every
    // possible end index of the subString
    for (r = n - 1; r >= 0; r--) {
        l = r;
    
        // Loop to find the subString
        // whose decimal equivalent is
        // greater than or equal to K
        while (l >= 0
               && (r - l + 1) <= 64
               && parseInt(s.substring(l, r + 1),2)
                      < k) {
            l--;
        }
    
        // Condition to check no
        // of bits is out of bound
        if (r - l + 1 <= 64)
            no_of_substr += l + 1;
        else {
            no_of_substr += arr[l + 1] + 1;
        }
    }
    return no_of_substr;
}
 
// Driver Code
let s = "11100";
let k = 3;
document.write(countSubstr(s, k));
 
 
 
// This code is contributed by unknown2108
</script>


Output

8






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();
    // Create a prefix sum array to store the decimal
   // value of each substring ending at index i
    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');
   }
 
   // Count the number of substrings whose decimal value is
  // greater than or equal to K
   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();
 
        // Create a prefix sum array to store the decimal
      // value of each substring ending at index i
        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');
        }
 
        // Count the number of substrings whose decimal
       // value is greater than or equal to K
        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)
     
    # Create a prefix sum array to store the decimal value of each substring ending at index i
    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])
 
    # Count the number of substrings whose decimal value is greater than or equal to K
    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;
        // Create a prefix sum array to store the decimal
        // value of each substring ending at index i
        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');
        }
 
        // Count the number of substrings whose decimal value is
        // greater than or equal to K
        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;
 
    // Create an array to store the prefix sum of binary values
    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));
    }
 
    // Count the number of substrings whose decimal value is greater than or equal to K
    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;
}
 
// Example usage
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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads