Count of Distinct Substrings occurring consecutively in a given String
Last Updated :
13 Nov, 2023
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"}
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: 1
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:
- 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
<script>
// Javascript Program to implement
// the above approach
// Function to count the distinct substrings
// placed consecutively in the given string
function distinctSimilarSubstrings(str)
{
// Length of the string
var n = str.length;
// If length of the string
// does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a DP-table
var dp = Array.from(Array(n+1), ()=>Array(n+1).fill(0));
// Stores the distinct substring
var substrings = new Set();
// Iterate from end of the string
for (var j = n - 1; j >= 0; j--) {
// Iterate backward until
// dp table is all computed
for (var 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.add(str.substring(i, j));
}
}
}
// Return the count
return substrings.size;
}
// Driver Code
var str = "geeksgeeksforgeeks";
document.write( distinctSimilarSubstrings(str));
// This code is contributed by noob2000.
</script>
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)
Similar Reads
Count of increasing substrings in given String
Given string str of length N, the task is to print the number of substrings in which every character's ASCII value is greater or equal to the ASCII value of the previous character. The substrings must at least be of length 2. Example: Input: str = "bcdabc"Output: 6Explanation: The 6 substrings with
7 min read
Find distinct characters in distinct substrings of a string
Given a string str, the task is to find the count of distinct characters in all the distinct sub-strings of the given string.Examples: Input: str = "ABCA" Output: 18 Distinct sub-stringsDistinct charactersA1AB2ABC3ABCA3B1BC2BCA3C1CA2 Hence, 1 + 2 + 3 + 3 + 1 + 2 + 3 + 1 + 2 = 18Input: str = "AAAB" O
5 min read
Maximum consecutive occurrences of a string in another given string
Given two strings str1 and str2, the task is to count the maximum consecutive occurrences of the string str2 in the string str1. Examples: Input: str1 = âabababcbaâ, str2 = âbaâ Output: 2 Explanation: String str2 occurs consecutively in the substring { str[1], ..., str[4] }. Therefore, the maximum c
7 min read
Count M-length substrings occurring exactly K times in a string
Given a string S of length N and two integers M and K, the task is to count the number of substrings of length M occurring exactly K times in the string S. Examples: Input: S = "abacaba", M = 3, K = 2Output: 1Explanation: All distinct substrings of length 3 are "aba", "bac", "aca", "cab".Out of all
15+ min read
Count number of distinct substrings of a given length
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 eq
6 min read
Count of Reverse Bitonic Substrings in a given String
Given a string S, the task is to count the number of Reverse Bitonic Substrings in the given string. Reverse bitonic substring: A string in which the ASCII values of the characters of the string follow any of the following patterns: Strictly IncreasingStrictly decreasingDecreasing and then increasin
8 min read
Count substrings made up of a single distinct character
Given a string S of length N, the task is to count the number of substrings made up of a single distinct character.Note: For the repetitive occurrences of the same substring, count all repetitions. Examples: Input: str = "geeksforgeeks"Output: 15Explanation: All substrings made up of a single distin
5 min read
Count of substrings having all distinct characters
Given a string str consisting of lowercase alphabets, the task is to find the number of possible substrings (not necessarily distinct) that consists of distinct characters only.Examples: Input: Str = "gffg" Output: 6 Explanation: All possible substrings from the given string are, ( "g", "gf", "gff",
7 min read
Count of distinct possible strings after performing given operations
Given a numeric string S consisting of only three types of characters 0, 1, and 2 initially and following two operations: The occurrence of two consecutive 1 can be replaced by 3.The occurrence of two consecutive 2 can be replaced by 4.The given task is to find the total number of different strings
10 min read
Count of Superstrings in a given array of strings
Given 2 array of strings X and Y, the task is to find the number of superstrings in X. A string s is said to be a Superstring, if each string present in array Y is a subsequence of string s . Examples: Input: X = {"ceo", "alco", "caaeio", "ceai"}, Y = {"ec", "oc", "ceo"}Output: 2Explanation: Strings
8 min read