Skip to content
Related Articles

Related Articles

Count of Distinct Substrings occurring consecutively in a given String
  • Difficulty Level : Hard
  • Last Updated : 28 Dec, 2020

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. 
Therefore, the answer is 2.

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

 

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

competitive-programming-img

My Personal Notes arrow_drop_up
Recommended Articles
Page :