Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Questions on Array
  • Practice Array
  • MCQs on Array
  • Tutorial on Array
  • Types of Arrays
  • Array Operations
  • Subarrays, Subsequences, Subsets
  • Reverse Array
  • Static Vs Arrays
  • Array Vs Linked List
  • Array | Range Queries
  • Advantages & Disadvantages
Open In App
Next Article:
Count substrings made up of a single distinct character
Next article icon

Count of distinct substrings of a string using Suffix Trie

Last Updated : 19 Sep, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string of length n of lowercase alphabet characters, we need to count total number of distinct substrings of this string. Examples:

Input  : str = “ababa”  Output : 10  Total number of distinct substring are 10, which are,  "", "a", "b", "ab", "ba", "aba", "bab", "abab", "baba"  and "ababa"
Recommended: Please solve it on “PRACTICE ” first, before moving on to the solution.

The idea is create a Trie of all suffixes of given string. Once the Trie is constricted, our answer is total number of nodes in the constructed Trie. For example below diagram represent Trie of all suffixes for “ababa”. Total number of nodes is 10 which is our answer. 

 

How does this work?

  • Each root to node path of a Trie represents a prefix of words present in Trie. Here we words are suffixes. So each node represents a prefix of suffixes.
  • Every substring of a string “str” is a prefix of a suffix of “str”.

Below is implementation based on above idea. 

C++




// A C++ program to find the count of distinct substring
// of a string using trie data structure
#include <bits/stdc++.h>
#define MAX_CHAR 26
using namespace std;
  
// A Suffix Trie (A Trie of all suffixes) Node
class SuffixTrieNode
{
public:
    SuffixTrieNode *children[MAX_CHAR];
    SuffixTrieNode() // Constructor
    {
        // Initialize all child pointers as NULL
        for (int i = 0; i < MAX_CHAR; i++)
          children[i] = NULL;
    }
  
    // A recursive function to insert a suffix of the s
    // in subtree rooted with this node
    void insertSuffix(string suffix);
};
  
// A Trie of all suffixes
class SuffixTrie
{
    SuffixTrieNode *root;
    int _countNodesInTrie(SuffixTrieNode *);
public:
    // Constructor (Builds a trie of suffies of the given text)
    SuffixTrie(string s)
    {
        root = new SuffixTrieNode();
  
        // Consider all suffixes of given string and insert
        // them into the Suffix Trie using recursive function
        // insertSuffix() in SuffixTrieNode class
        for (int i = 0; i < s.length(); i++)
            root->insertSuffix(s.substr(i));
    }
  
    //  method to count total nodes in suffix trie
    int countNodesInTrie() { return _countNodesInTrie(root); }
};
  
// A recursive function to insert a suffix of the s in
// subtree rooted with this node
void SuffixTrieNode::insertSuffix(string s)
{
    // If string has more characters
    if (s.length() > 0)
    {
        // Find the first character and convert it
        // into 0-25 range.
        char cIndex = s.at(0) - 'a';
  
        // If there is no edge for this character,
        // add a new edge
        if (children[cIndex] == NULL)
            children[cIndex] = new SuffixTrieNode();
  
        // Recur for next suffix
        children[cIndex]->insertSuffix(s.substr(1));
    }
}
  
// A recursive function to count nodes in trie
int SuffixTrie::_countNodesInTrie(SuffixTrieNode* node)
{
    // If all characters of pattern have been processed,
    if (node == NULL)
        return 0;
  
    int count = 0;
    for (int i = 0; i < MAX_CHAR; i++)
    {
        // if children is not NULL then find count
        // of all nodes in this subtrie
        if (node->children[i] != NULL)
            count += _countNodesInTrie(node->children[i]);
    }
  
    // return count of nodes of subtrie and plus
    // 1 because of node's own count
    return (1 + count);
}
  
// Returns count of distinct substrings of str
int countDistinctSubstring(string str)
{
    // Construct a Trie of all suffixes
    SuffixTrie sTrie(str);
  
    // Return count of nodes in Trie of Suffixes
    return sTrie.countNodesInTrie();
}
  
// Driver program to test above function
int main()
{
    string str = "ababa";
    cout << "Count of distinct substrings is "
         << countDistinctSubstring(str);
    return 0;
}
 
 

Java




// A Java program to find the count of distinct substring
// of a string using trie data structure
public class Suffix 
{
    // A Suffix Trie (A Trie of all suffixes) Node
    static class SuffixTrieNode
    {
        static final int MAX_CHAR = 26;
        SuffixTrieNode[] children = new SuffixTrieNode[MAX_CHAR];
  
        SuffixTrieNode() // Constructor
        {
            // Initialize all child pointers as NULL
            for (int i = 0; i < MAX_CHAR; i++)
                children[i] = null;
        }
  
        // A recursive function to insert a suffix of the s in
        // subtree rooted with this node
        void insertSuffix(String s) 
        {
            // If string has more characters
            if (s.length() > 0) 
            {
                // Find the first character and convert it
                // into 0-25 range.
                char cIndex = (char) (s.charAt(0) - 'a');
  
                // If there is no edge for this character,
                // add a new edge
                if (children[cIndex] == null)
                    children[cIndex] = new SuffixTrieNode();
  
                // Recur for next suffix
                children[cIndex].insertSuffix(s.substring(1));
                }
        }
    }
      
    // A Trie of all suffixes
    static class Suffix_trie 
    {
        static final int MAX_CHAR = 26;
        SuffixTrieNode root;
  
        // Constructor (Builds a trie of suffies of the given text)
        Suffix_trie(String s) {
            root = new SuffixTrieNode();
  
            // Consider all suffixes of given string and insert
            // them into the Suffix Trie using recursive function
            // insertSuffix() in SuffixTrieNode class
            for (int i = 0; i < s.length(); i++)
                root.insertSuffix(s.substring(i));
        }
  
        // A recursive function to count nodes in trie
        int _countNodesInTrie(SuffixTrieNode node) 
        {
            // If all characters of pattern have been processed,
            if (node == null)
                return 0;
  
            int count = 0;
            for (int i = 0; i < MAX_CHAR; i++) {
  
                // if children is not NULL then find count
                // of all nodes in this subtrie
                if (node.children[i] != null)
                    count += _countNodesInTrie(node.children[i]);
            }
  
            // return count of nodes of subtrie and plus
            // 1 because of node's own count
            return (1 + count);
        }
  
        // method to count total nodes in suffix trie
        int countNodesInTrie() 
        {
            return _countNodesInTrie(root);
        }
  
    } 
  
    // Returns count of distinct substrings of str
    static int countDistinctSubstring(String str)
    {
        // Construct a Trie of all suffixes
        Suffix_trie sTrie = new Suffix_trie(str);
  
        // Return count of nodes in Trie of Suffixes
        return sTrie.countNodesInTrie();
    }
  
    // Driver program to test above function
    public static void main(String args[]) 
    {
        String str = "ababa";
        System.out.println("Count of distinct substrings is "
                + countDistinctSubstring(str));
          
    }
}
// This code is contributed by Sumit Ghosh
 
 

Python3




# Python program to find the count of distinct substring
# of a string using trie data structure
  
# A Suffix Trie (A Trie of all suffixes) Node
class SuffixTrieNode:
    def __init__(self):
        # Initialize all child pointers as NULL
        self.children = [None] * 26
      
    # A recursive function to insert a suffix of the s in
    # subtree rooted with this node
    def insert_suffix(self, suffix):
        # If string has more characters
        if suffix:
            # Find the first character and convert it
            # into 0-25 range.
            c_index = ord(suffix[0]) - ord('a')
            # If there is no edge for this character,
            # add a new edge
            if not self.children[c_index]:
                self.children[c_index] = SuffixTrieNode()
            # Recur for next suffix
            self.children[c_index].insert_suffix(suffix[1:])
  
# A Trie of all suffixes
class SuffixTrie:
    def __init__(self, s):
        # Constructor (Builds a trie of suffies of the given text)
        self.root = SuffixTrieNode()
        for i in range(len(s)):
            # Consider all suffixes of given string and insert
            # them into the Suffix Trie using recursive function
            # insertSuffix() in SuffixTrieNode class
            self.root.insert_suffix(s[i:])
      
    # method to count total nodes in suffix trie
    def countNodesInTrie(self):
        return self._countNodesInTrie(self.root)
      
    def _countNodesInTrie(self, node):
        # If all characters of pattern have been processed,
        if node is None:
            return 0
        count = 0
        for i in range(26):
            # if children is not NULL then find count
            # of all nodes in this subtrie
            if node.children[i]:
                count += self._countNodesInTrie(node.children[i])
        # return count of nodes of subtrie and plus
        # 1 because of node's own count
        return count + 1
  
# Returns count of distinct substrings of str
def countDistinctSubstring(str):
    # Construct a Trie of all suffixes
    s_trie = SuffixTrie(str)
    # Return count of nodes in Trie of Suffixes
    return s_trie.countNodesInTrie()
  
# Driver program to test above function
if __name__ == '__main__':
    str = "ababa"
    print("Count of distinct substrings is", countDistinctSubstring(str))
  
# This code is contributed by Aman Kumar.
 
 

C#




// C# program to find the count of distinct substring
// of a string using trie data structure
using System;
  
public class Suffix 
{
    // A Suffix Trie (A Trie of all suffixes) Node
    public class SuffixTrieNode
    {
        static readonly int MAX_CHAR = 26;
        public SuffixTrieNode[] children = new SuffixTrieNode[MAX_CHAR];
  
        public SuffixTrieNode() // Constructor
        {
            // Initialize all child pointers as NULL
            for (int i = 0; i < MAX_CHAR; i++)
                children[i] = null;
        }
  
        // A recursive function to insert a suffix of the s in
        // subtree rooted with this node
        public void insertSuffix(String s) 
        {
            // If string has more characters
            if (s.Length > 0) 
            {
                // Find the first character and convert it
                // into 0-25 range.
                char cIndex = (char) (s[0] - 'a');
  
                // If there is no edge for this character,
                // add a new edge
                if (children[cIndex] == null)
                    children[cIndex] = new SuffixTrieNode();
  
                // Recur for next suffix
                children[cIndex].insertSuffix(s.Substring(1));
                }
        }
    }
      
    // A Trie of all suffixes
    public class Suffix_trie 
    {
        static readonly int MAX_CHAR = 26;
        public SuffixTrieNode root;
  
        // Constructor (Builds a trie of suffies of the given text)
        public Suffix_trie(String s) 
        {
            root = new SuffixTrieNode();
  
            // Consider all suffixes of given string and insert
            // them into the Suffix Trie using recursive function
            // insertSuffix() in SuffixTrieNode class
            for (int i = 0; i < s.Length; i++)
                root.insertSuffix(s.Substring(i));
        }
  
        // A recursive function to count nodes in trie
        public int _countNodesInTrie(SuffixTrieNode node) 
        {
            // If all characters of pattern have been processed,
            if (node == null)
                return 0;
  
            int count = 0;
            for (int i = 0; i < MAX_CHAR; i++) 
            {
  
                // if children is not NULL then find count
                // of all nodes in this subtrie
                if (node.children[i] != null)
                    count += _countNodesInTrie(node.children[i]);
            }
  
            // return count of nodes of subtrie and plus
            // 1 because of node's own count
            return (1 + count);
        }
  
        // method to count total nodes in suffix trie
        public int countNodesInTrie() 
        {
            return _countNodesInTrie(root);
        }
  
    } 
  
    // Returns count of distinct substrings of str
    static int countDistinctSubstring(String str)
    {
        // Construct a Trie of all suffixes
        Suffix_trie sTrie = new Suffix_trie(str);
  
        // Return count of nodes in Trie of Suffixes
        return sTrie.countNodesInTrie();
    }
  
    // Driver program to test above function
    public static void Main(String []args) 
    {
        String str = "ababa";
        Console.WriteLine("Count of distinct substrings is "
                + countDistinctSubstring(str));
          
    }
}
  
// This code contributed by Rajput-Ji
 
 

Javascript




// A Javascript program to find the count of distinct substring
// of a string using trie data structure
// A Suffix Trie (A Trie of all suffixes) Node
class SuffixTrieNode {
    constructor() {
        // Initialize all child pointers as null
        this.children = new Array(26).fill(null);
    }
  
    // A recursive function to insert a suffix of the s in
    // subtree rooted with this node
    insertSuffix(suffix) {
      
        // If string has more characters
        if (suffix.length > 0) {
            // Find the first character and convert it
            // into 0-25 range.
            const cIndex = suffix.charCodeAt(0) - 'a'.charCodeAt(0);
            // If there is no edge for this character,
            // add a new edge
            if (!this.children[cIndex]) {
                this.children[cIndex] = new SuffixTrieNode();
            }
            // Recur for next suffix
            this.children[cIndex].insertSuffix(suffix.slice(1));
        }
    }
}
  
// A Trie of all suffixes
class SuffixTrie {
    constructor(s) {
        // Constructor (Builds a trie of suffies of the given text)
        this.root = new SuffixTrieNode();
        for (let i = 0; i < s.length; i++) {
          
            // Consider all suffixes of given string and insert
            // them into the Suffix Trie using recursive function
            // insertSuffix() in SuffixTrieNode class
            this.root.insertSuffix(s.slice(i));
        }
    }
  
    // method to count total nodes in suffix trie
    countNodesInTrie() {
        return this._countNodesInTrie(this.root);
    }
  
    _countNodesInTrie(node) {
        // If all characters of pattern have been processed,
        if (node === null) {
            return 0;
        }
        let count = 0;
        for (let i = 0; i < 26; i++) {
          
            // if children is not null then find count
            // of all nodes in this subtrie
            if (node.children[i]) {
                count += this._countNodesInTrie(node.children[i]);
            }
        }
          
        // return count of nodes of subtrie and plus
        // 1 because of node's own count
        return count + 1;
    }
}
  
// Returns count of distinct substrings of str
function countDistinctSubstring(str) {
  
    // Construct a Trie of all suffixes
    const sTrie = new SuffixTrie(str);
      
    // Return count of nodes in Trie of Suffixes
    return sTrie.countNodesInTrie();
}
  
// Driver program to test above function
const str = 'ababa';
console.log('Count of distinct substrings is', countDistinctSubstring(str));
 
 
Output
Count of distinct substrings is 10

Time Complexity: O(n2), where n is the length of string.
Auxiliary Space: O(n)

We will soon be discussing Suffix Array and Suffix Tree based approaches for this problem.



Next Article
Count substrings made up of a single distinct character

U

Utkarsh Trivedi
Improve
Article Tags :
  • Advanced Data Structure
  • Arrays
  • DSA
  • Strings
  • Suffix-Tree
  • Trie
Practice Tags :
  • Advanced Data Structure
  • Arrays
  • Strings
  • Trie

Similar Reads

  • Count of distinct substrings of a string using Suffix Array
    Given a string of length n of lowercase alphabet characters, we need to count total number of distinct substrings of this string.  Examples:  Input : str = “ababa” Output : 10 Total number of distinct substring are 10, which are, "", "a", "b", "ab", "ba", "aba", "bab", "abab", "baba" and "ababa"Reco
    15+ min read
  • Count distinct substrings of a string using Rabin Karp algorithm
    Given a string, return the number of distinct substrings using Rabin Karp Algorithm. Examples: Input : str = “aba”Output : 5Explanation :Total number of distinct substring are 5 - "a", "ab", "aba", "b" ,"ba" Input : str = “abcd”Output : 10Explanation :Total number of distinct substring are 10 - "a",
    9 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
  • Split the string into substrings using delimiter
    Given a string and a delimiter character. Split the string based on the delimiter and print the list of resulting sub strings. Examples: Input : str = "geeks;for;geeks" d_ch = ';' Output : geeks for geeks Input : str = "##ayush##jauhari####" d_ch = '#' Output : ayush jauhari Source: Microsoft IDC Ba
    6 min read
  • Count the sum of count of distinct characters present in all Substrings
    Given a string S consisting of lowercase English letters of size N where (1 <= N <= 105), the task is to print the sum of the count of distinct characters N where (1 <= N <= 105)in all the substrings. Examples: Input: str = "abbca"Output: 28Explanation: The following are the substrings o
    8 min read
  • Count Substrings with all Unique Digits in Range [0, K]
    Given a string S of length N (1 <= N <= 107) and a positive integer K, where the string contains only numbers in the range [0, 9], the task is to determine the count of substrings that include at least one occurrence of all the unique digits within the specified range [0, K]. Example: Input: S
    9 min read
  • Count the number of vowels occurring in all the substrings of given string
    Given a string of length N of lowercase characters containing 0 or more vowels, the task is to find the count of vowels that occurred in all the substrings of the given string. Examples: Input: str = "abc" Output: 3The given string "abc" contains only one vowel = 'a' Substrings of "abc" are = {"a",
    12 min read
  • Pattern Searching using a Trie of all Suffixes
    Problem Statement: Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] in txt[]. You may assume that n > m.As discussed in the previous post, we discussed that there are two ways efficiently solve the above probl
    13 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
  • Count of substrings of a string containing another given string as a substring
    Given two strings S and T, the task is to count the number of substrings of S that contains string T in it as a substring. Examples: Input: S = "dabc", T = "ab"Output: 4Explanation: Substrings of S containing T as a substring are: S[0, 2] = “dab”S[1, 2] = “ab”S[1, 3] = “abc”S[0, 3] = “dabc” Input: S
    8 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences