Count number of distinct substrings of a given length
Last Updated :
31 May, 2022
Given a string S of length N consisting of lower-case English alphabets and an integer ‘l’, find the number of distinct substrings of length ‘l’ of the given string.
Examples:
Input : s = “abcbab”, l = 2
Output : 4
All distinct sub-strings of length 2
will be {“ab”, “bc”, “cb”, “ba”}
Thus, answer equals 4.
Input : s = “ababa”, l = 2
Output : 2
Naive Approach :
A simple approach will be to find all the possible substrings, find their hash values and find the number of distinct substrings.
Time Complexity: O(l*N)
Efficient approach :
We will solve this problem using Rolling hash algorithm.
- Find the hash value of first sub-string of length ‘l’.
It can be evaluated as (s[0]-97)*x^(l-1) + (s[1]-97)*x^(l-2) … (s[l-1]-97). Let’s call this ‘H₁’.
- Using this hash value, we will generate the next hash as :
H2 = (H1-(s[0]-97)*x^(l-1)*x + (s[l]-97). Generate hashes of all substrings in this way
and push them in an unordered set.
- Count number of distinct values in the set.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
#define x 26
#define mod 3001
using namespace std;
int CntSubstr(string s, int l)
{
int hash = 0;
for ( int i = 0; i < l; i++) {
hash = (hash * x + (s[i] - 97)) % mod;
}
int pow_l = 1;
for ( int i = 0; i < l - 1; i++)
pow_l = (pow_l * x) % mod;
unordered_set< int > result;
result.insert(hash);
for ( int i = l; i < s.size(); i++) {
hash = ((hash - pow_l * (s[i - l] - 97)
+ 2 * mod) * x + (s[i] - 97)) % mod;
result.insert(hash);
}
cout << result.size() << endl;
}
int main()
{
string s = "abcba" ;
int l = 2;
CntSubstr(s, l);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int x = 26 ;
static int mod = 3001 ;
static void CntSubstr( char [] s, int l)
{
int hash = 0 ;
for ( int i = 0 ; i < l; i++)
{
hash = (hash * x + (s[i] - 97 )) % mod;
}
int pow_l = 1 ;
for ( int i = 0 ; i < l - 1 ; i++)
{
pow_l = (pow_l * x) % mod;
}
HashSet<Integer> result = new HashSet<Integer>();
result.add(hash);
for ( int i = l; i < s.length; i++)
{
hash = ((hash - pow_l * (s[i - l] - 97 )
+ 2 * mod) * x + (s[i] - 97 )) % mod;
result.add(hash);
}
System.out.println(result.size());
}
public static void main(String[] args)
{
String s = "abcba" ;
int l = 2 ;
CntSubstr(s.toCharArray(), l);
}
}
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int x = 26;
static int mod = 3001;
static void CntSubstr( char [] s, int l)
{
int hash = 0;
for ( int i = 0; i < l; i++)
{
hash = (hash * x + (s[i] - 97)) % mod;
}
int pow_l = 1;
for ( int i = 0; i < l - 1; i++)
{
pow_l = (pow_l * x) % mod;
}
HashSet< int > result = new HashSet< int >();
result.Add(hash);
for ( int i = l; i < s.Length; i++)
{
hash = ((hash - pow_l * (s[i - l] - 97)
+ 2 * mod) * x + (s[i] - 97)) % mod;
result.Add(hash);
}
Console.WriteLine(result.Count);
}
public static void Main(String[] args)
{
String s = "abcba" ;
int l = 2;
CntSubstr(s.ToCharArray(), l);
}
}
|
Python3
x = 26
mod = 3001
def CntSubstr(s, l) :
hash = 0 ;
for i in range (l) :
hash = ( hash * x + ( ord (s[i]) - 97 )) % mod;
pow_l = 1 ;
for i in range (l - 1 ) :
pow_l = (pow_l * x) % mod;
result = set ();
result.add( hash );
for i in range (l, len (s)) :
hash = (( hash - pow_l * ( ord (s[i - l]) - 97 )
+ 2 * mod) * x + ( ord (s[i]) - 97 )) % mod;
result.add( hash );
print ( len (result)) ;
if __name__ = = "__main__" :
s = "abcba" ;
l = 2 ;
CntSubstr(s, l);
|
Javascript
<script>
var x = 26;
var mod = 3001;
function CntSubstr(s, l)
{
var hash = 0;
for ( var i = 0; i < l; i++) {
hash = (hash * x + (s[i].charCodeAt(0) - 97)) % mod;
}
var pow_l = 1;
for ( var i = 0; i < l - 1; i++)
pow_l = (pow_l * x) % mod;
var result = new Set();
result.add(hash);
for ( var i = l; i < s.length; i++) {
hash = ((hash - pow_l * (s[i - l].charCodeAt(0) - 97)
+ 2 * mod) * x + (s[i].charCodeAt(0) - 97)) % mod;
result.add(hash);
}
document.write( result.size );
}
var s = "abcba" ;
var l = 2;
CntSubstr(s, l);
</script>
|
Time Complexity : O(N)
Auxiliary Space: O(|s|)
Share your thoughts in the comments
Please Login to comment...