Count of Distinct Substrings occurring consecutively in a given String (original) (raw)
Last Updated : 15 Jul, 2025
Given a string **str, the task is to find the number of **distinct substrings that are placed consecutively in the given string.
**Examples:
Input: str = "geeksgeeksforgeeks"
Output: 2
Explanation:
geeksgeeksforgeeks -> {"geeks"}
g**ee**ksgeeksforgee**ks -> {"e"}
Only one consecutive occurrence of "e" is considered.
Therefore two distinct substrings {"geeks", "e"} occur consecutively in the string.
Therefore, the answer is 2.*Input: s = "geeksforgeeks"
Output: 1
Explanation:
gee*ksgeeksforgeeks -> {"e", "e"}
Only one substring {"e"} occurs consecutively in the string.
**Naive Approach:
The simplest approach is to generate all possible substrings of the given string, and for each substring, find the **count of substrings in the given occurring consecutively in the string. Finally, print the count.
**Time Complexity: O(N3)
**Auxiliary Space: O(N)
**Efficient Approach:
To optimize the above approach, the idea is to use Dynamic Programming.
Follow the steps below to solve the problem:
- If the length of the string does **not exceed 1, then it is not possible to find any such consecutively placed similar substrings. So **return 0 as the **count.
- Otherwise, initialize a memoization table **dp[] of dimensions ****(N+1 * N+1)** which is initialized to **0.
- Initialize an **unordered_set to store the distinct substrings placed consecutively.
- Iterate from the end of the string.
- While traversing the string if any **repeating character is found, then **dp[i][j] will be determined considering the previously computed dp value i.e., count of identical substrings up to **dp[i+1][j+1] characters and including the current character.
- If the character is not similar then, **dp[i][j] will be filled with 0.
- Similar substrings are consecutively placed together without any other characters and they will be the same for at most ****(j - i)** characters. Hence, for valid substrings, **dp[i][j] value must be greater than (j - i). Store those substrings in **unordered_set which appears the maximum number of times consecutively.
- Finally, return the size of the **unordered_set as the count of distinct substrings placed consecutively.
Below is the implementation of the above approach:
C++ `
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to count the distinct substrings // placed consecutively in the given string int distinctSimilarSubstrings(string str) { // Length of the string int n = str.size();
// If length of the string
// does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a DP-table
vector<vector<int> > dp(
n + 1, vector<int>(n + 1, 0));
// Stores the distinct substring
unordered_set<string> substrings;
// Iterate from end of the string
for (int j = n - 1; j >= 0; j--) {
// Iterate backward until
// dp table is all computed
for (int i = j - 1; i >= 0; i--) {
// If character at i-th index is
// same as character at j-th index
if (str[i] == str[j]) {
// Update dp[i][j] based on
// previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1;
}
// Otherwise
else {
dp[i][j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i][j] >= j - i) {
substrings.insert(
str.substr(i, j - i));
}
}
}
// Return the count
return substrings.size();}
// Driver Code int main() { string str = "geeksgeeksforgeeks";
cout << distinctSimilarSubstrings(str);
return 0;}
Java
// Java program to implement // the above approach import java.io.*; import java.util.ArrayList;
class GFG{
// Function to count the distinct substrings
// placed consecutively in the given string
static int distinctSimilarSubstrings(String str)
{
// Length of the string
int n = str.length();
// If length of the string
// does not exceed 1
if (n <= 1)
return 0;
// Initialize a DP-table
long dp[][] = new long[n + 1][n + 1];
// Declaring ArrayList to store strings
ArrayList<String> list = new ArrayList<String>();
// Iterate from end of the string
for(int j = n - 1; j >= 0; j--)
{
// Iterate backward until
// dp table is all computed
for(int i = j - 1; i >= 0; i--)
{
// If character at i-th index is
// same as character at j-th index
if (str.charAt(i) == str.charAt(j))
{
// Update dp[i][j] based on
// previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1;
}
// Otherwise
else
{
dp[i][j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i][j] >= j - i)
{
list.add(str.substring(j - i, i));
}
}
}
// Return the count
return list.size();}
// Driver Code public static void main(String[] args) { String str = "geeksforgeeks";
System.out.println(distinctSimilarSubstrings(str));} }
// This code is contributed by user_00
Python3
Python3 program to implement
the above approach
Function to count the distinct substrings
placed consecutively in the given string
def distinctSimilarSubstrings(str):
# Length of the string
n = len(str)
# If length of the string
# does not exceed 1
if(n <= 1):
return 0
# Initialize a DP-table
dp = [[0 for x in range(n + 1)]
for y in range(n + 1)]
# Stores the distinct substring
substrings = set()
# Iterate from end of the string
for j in range(n - 1, -1, -1):
# Iterate backward until
# dp table is all computed
for i in range(j - 1, -1, -1):
# If character at i-th index is
# same as character at j-th index
if(str[i] == str[j]):
# Update dp[i][j] based on
# previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1
# Otherwise
else:
dp[i][j] = 0
# Condition for consecutively
# placed similar substring
if(dp[i][j] >= j - i):
substrings.add(str[i : j - i])
# Return the count
return len(substrings)Driver Code
str = "geeksgeeksforgeeks"
Function call
print(distinctSimilarSubstrings(str))
This code is contributed by Shivam Singh
C#
// C# program to implement // the above approach using System; using System.Collections.Generic; class GFG {
// Function to count the distinct substrings
// placed consecutively in the given string
static int distinctSimilarSubstrings(string str)
{
// Length of the string
int n = str.Length;
// If length of the string
// does not exceed 1
if (n <= 1)
return 0;
// Initialize a DP-table
long[,] dp = new long[n + 1, n + 1];
// Declaring ArrayList to store strings
List<string> list = new List<string>();
// Iterate from end of the string
for(int j = n - 1; j >= 0; j--)
{
// Iterate backward until
// dp table is all computed
for(int i = j - 1; i >= 0; i--)
{
// If character at i-th index is
// same as character at j-th index
if (str[i] == str[j])
{
// Update dp[i][j] based on
// previously computed value
dp[i, j] = dp[i + 1, j + 1] + 1;
}
// Otherwise
else
{
dp[i, j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i, j] >= j - i)
{
list.Add(str.Substring(i, j - i));
}
}
}
// Return the count
return list.Count;
} // Driver code
static void Main()
{
string str = "geeksforgeeks";
Console.WriteLine(distinctSimilarSubstrings(str));
}
}
// This code is contributed by divyesh072019
JavaScript
`
**Time Complexity: O(N^2)
**Auxiliary Space: O(N^2)
**Efficient approach: Space optimization
In previous approach the **dp[i][j] is depend upon the current and previous row of 2D matrix. So to optimize space we use two vectors **curr and **prev that keep track of current and previous row of DP.
**Implementation Steps:
- Initialize a vectors **prev of size **N+1 to keep track of only previous row of **Dp with **0.
- Now iterative over subproblems and get the current computation.
- While Initialize a vectors **curr of size **N+1 to keep track of only current row of **Dp with **0.
- Now compute the current value by the help of **prev vector and store that value in **curr.
- After every iteration store values of **curr vector in **prev vector for further iterration.
- At last create substring and return its size.
**Implementation:
C++ `
// C++ program for above approach
#include <bits/stdc++.h> using namespace std;
// Function to count the distinct substrings // placed consecutively in the given string int distinctSimilarSubstrings(string str) { // Length of the string int n = str.size();
// If length of the string
// does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a previous row of dp-table
vector<int> prev(n + 1, 0);
// Stores the count of distinct substring
unordered_map<string, int> substrings;
// Iterate from end of the string
for (int j = n - 1; j >= 0; j--) {
// Initialize the current row of dp-table
vector<int> cur(n + 1, 0);
// Iterate backward until
// dp table is all computed
for (int i = j - 1; i >= 0; i--) {
// If character at i-th index is
// same as character at j-th index
if (str[i] == str[j]) {
// Update cur[i] based on
// previously computed value
cur[i] = prev[i + 1] + 1;
}
// Otherwise
else {
cur[i] = 0;
}
// Condition for consecutively
// placed similar substring
if (cur[i] >= j - i) {
substrings[str.substr(i, j - i)]++;
}
}
// Copy the current row to previous row
prev = cur;
}
// Return the count
return substrings.size();}
// Driver Code int main() { string str = "geeksgeeksforgeeks";
cout << distinctSimilarSubstrings(str);
return 0;} // this code is contributed by bhardwajji
Java
import java.util.*;
public class Main {
// Function to count the distinct substrings // placed consecutively in the given string public static int distinctSimilarSubstrings(String str) {
// Length of the string
int n = str.length();
// If length of the string does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a previous row of dp-table
int[] prev = new int[n + 1];
// Stores the count of distinct substring
HashMap<String, Integer> substrings = new HashMap<>();
// Iterate from end of the string
for (int j = n - 1; j >= 0; j--) {
// Initialize the current row of dp-table
int[] cur = new int[n + 1];
// Iterate backward until dp table is all computed
for (int i = j - 1; i >= 0; i--) {
// If character at i-th index is same as character at j-th index
if (str.charAt(i) == str.charAt(j)) {
// Update cur[i] based on previously computed value
cur[i] = prev[i + 1] + 1;
}
// Otherwise
else {
cur[i] = 0;
}
// Condition for consecutively placed similar substring
if (cur[i] >= j - i) {
substrings.merge(str.substring(i, j), 1, Integer::sum);
}
}
// Copy the current row to previous row
prev = cur;
}
// Return the count
return substrings.size();}
// Driver Code public static void main(String[] args) { String str = "geeksgeeksforgeeks"; System.out.println(distinctSimilarSubstrings(str)); } }
Python3
def distinctSimilarSubstrings(s): n = len(s)
# If the length of the string is 0 or 1, there are no substrings to count.
if n <= 1:
return 0
# Initialize a list to store the previous row of the dynamic programming table.
prev = [0] * (n + 1)
# Create a dictionary to store the count of distinct substrings.
substrings = {}
# Iterate through the string in reverse order, from the end to the beginning.
for j in range(n - 1, -1, -1):
# Initialize a list to represent the current row of the dynamic programming table.
cur = [0] * (n + 1)
# Iterate backward from the current position (j-1) to the beginning of the string.
for i in range(j - 1, -1, -1):
# If the characters at positions i and j are the same, increment the count
# of similar characters by one based on the previous row value.
if s[i] == s[j]:
cur[i] = prev[i + 1] + 1
else:
# If the characters are not the same, reset the count to zero.
cur[i] = 0
# Check if the count of similar characters (cur[i]) is greater than or equal to
# the length of the substring (j - i). If true, it means the substring is
# consecutively placed.
if cur[i] >= j - i:
# Add the substring to the dictionary and increment its count.
substrings[s[i:i + j - i]] = substrings.get(s[i:i + j - i], 0) + 1
# Update the previous row to the current row for the next iteration.
prev = cur
# Return the count of distinct substrings.
return len(substrings)if name == "main": str = "geeksgeeksforgeeks" print(distinctSimilarSubstrings(str))
C#
using System; using System.Collections.Generic;
class GFG { // Function to count the distinct substrings // placed consecutively in the given string static int DistinctSimilarSubstrings(string str) { // Length of the string int n = str.Length;
// If the length of the string does not exceed 1
if (n <= 1)
{
return 0;
}
// Initialize a previous row of dp-table
int[] prev = new int[n + 1];
// Stores the count of distinct substring
Dictionary<string, int> substrings = new Dictionary<string, int>();
// Iterate from the end of the string
for (int j = n - 1; j >= 0; j--)
{
// Initialize the current row of dp-table
int[] cur = new int[n + 1];
// Iterate backward until the dp table is all computed
for (int i = j - 1; i >= 0; i--)
{
// If the character at i-th index is the same as the character at j-th index
if (str[i] == str[j])
{
// Update cur[i] based on the previously computed value
cur[i] = prev[i + 1] + 1;
}
// Otherwise
else
{
cur[i] = 0;
}
// Condition for consecutively placed similar substring
if (cur[i] >= j - i)
{
substrings[str.Substring(i, j - i)] = substrings.GetValueOrDefault(str.Substring(i, j - i), 0) + 1;
}
}
// Copy the current row to the previous row
prev = cur;
}
// Return the count
return substrings.Count;
}
// Driver Code
public static void Main()
{
string str = "geeksgeeksforgeeks";
Console.WriteLine(DistinctSimilarSubstrings(str));
}}
JavaScript
// Function to count the distinct substrings // placed consecutively in the given string function distinctSimilarSubstrings(str) { // Length of the string let n = str.length;
// If length of the string does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a previous row of dp-table
let prev = new Array(n + 1).fill(0);
// Stores the count of distinct substring
let substrings = {};
// Iterate from end of the string
for (let j = n - 1; j >= 0; j--) {
// Initialize the current row of dp-table
let cur = new Array(n + 1).fill(0);
// Iterate backward until dp table is all computed
for (let i = j - 1; i >= 0; i--) {
// If character at i-th index is same as character at j-th index
if (str[i] == str[j]) {
// Update cur[i] based on previously computed value
cur[i] = prev[i + 1] + 1;
}
// Otherwise
else {
cur[i] = 0;
}
// Condition for consecutively placed similar substring
if (cur[i] >= j - i) {
substrings[str.substr(i, j - i)]++;
}
}
// Copy the current row to previous row
prev = cur;
}
// Return the count
return Object.keys(substrings).length;}
// Driver Code let str = "geeksgeeksforgeeks";
console.log(distinctSimilarSubstrings(str));
`
**Time Complexity: O(N^2)
**Auxiliary Space: O(N)