Count of Distinct Substrings occurring consecutively in a given String

• Difficulty Level : Hard
• Last Updated : 07 Jun, 2021

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:
Explanation:
geeksgeeksforgeeks -> {“geeks”}
geeksgeeksforgeeks -> {“e”}
Only one consecutive occurrence of “e” is considered.
Therefore two distinct substrings {“geeks”, “e”} occur consecutively in the string.

Input: s = “geeksforgeeks”
Output:
Explanation:
geeksgeeksforgeeks -> {“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 using namespace std; // Function to count the distinct substrings// placed consecutively in the given stringint 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 > dp(        n + 1, vector(n + 1, 0));     // Stores the distinct substring    unordered_set 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 Codeint main(){    string str = "geeksgeeksforgeeks";     cout << distinctSimilarSubstrings(str);    return 0;}

Java

 // Java program to implement// the above approachimport 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 list = new ArrayList();     // 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 Codepublic 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 stringdef 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 Codestr = "geeksgeeksforgeeks" # Function callprint(distinctSimilarSubstrings(str)) # This code is contributed by Shivam Singh

C#

 // C# program to implement// the above approachusing 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 list = new List();              // 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


Output:
2

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up