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**ksg
eeksforg
ee**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:
g
ee
*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:

  1. 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.
  2. Otherwise, initialize a memoization table **dp[] of dimensions ****(N+1 * N+1)** which is initialized to **0.
  3. Initialize an **unordered_set to store the distinct substrings placed consecutively.
  4. Iterate from the end of the string.
  5. 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.
  6. If the character is not similar then, **dp[i][j] will be filled with 0.
  7. 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.
  8. 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:

**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)