Skip to main content

Implement Trie - II

Problem Statement:​

Ninja has to implement a data structure ”TRIE” from scratch. Ninja has to complete some functions.

1) Trie(): Ninja has to initialize the object of this “TRIE” data structure.

2) insert(“WORD”): Ninja has to insert the string “WORD” into this “TRIE” data structure.

3) countWordsEqualTo(“WORD”): Ninja has to return how many times this “WORD” is present in this “TRIE”.

4) countWordsStartingWith(“PREFIX”): Ninjas have to return how many words are there in this “TRIE” that have the string “PREFIX” as a prefix.

5) erase(“WORD”): Ninja has to delete one occurrence of the string “WORD” from the “TRIE”.

Note:

1. If erase(“WORD”) function is called then it is guaranteed that the “WORD” is present in the “TRIE”.

2. If you are going to use variables with dynamic memory allocation then you need to release the memory associated with them at the end of your solution.

Can you help Ninja implement the "TRIE" data structure?

  • Example:

    Sample Input 1:

    1
    5
    insert coding
    insert ninja
    countWordsEqualTo coding
    countWordsStartingWith nin
    erase coding

    Sample Output 1:

    1
    1

    Explanation of sample input 1:

    After insertion of “coding” in “TRIE”:

    After insertion of “ninja” in “TRIE”:

    Count words equal to “coding” :

    Count words those prefix is “nin”:

    After deletion of the word “coding”, “TRIE” is:

    Sample Input 2:

    1
    6
    insert samsung
    insert samsung
    insert vivo
    erase vivo
    countWordsEqualTo samsung
    countWordsStartingWith vi

    Sample Output 2:

    2
    0

    Explanation for sample input 2:

    insert “samsung”: we are going to insert the word “samsung” into the “TRIE”.

    insert “samsung”: we are going to insert another “samsung” word into the “TRIE”.

    insert “vivo”: we are going to insert the word “vivo” into the “TRIE”.

    erase “vivo”: we are going to delete the word “vivo” from the “TRIE”.

    countWordsEqualTo “samsung”: There are two instances of “sumsung” is present in “TRIE”.

    countWordsStartingWith “vi”: There is not a single word in the “TRIE” that starts from the prefix “vi”.

✅ Solution: Trie with Frequency Count (Enhanced Trie)​

#include <bits/stdc++.h>
using namespace std;

class Node {
public:
Node *links[26]; // Links to child nodes for 'a' to 'z'
int countEndWith = 0; // Number of words ending at this node
int countPrefix = 0; // Number of words with prefix up to this node

bool contains(char ch) {
return links[ch - 'a'] != NULL;
}

void put(char ch, Node *node) {
links[ch - 'a'] = node;
}

Node* get(char ch) {
return links[ch - 'a'];
}

void increasePrefix() {
countPrefix++;
}

void increaseEnd() {
countEndWith++;
}

void decreasePrefix() {
countPrefix--;
}

void decreaseEnd() {
countEndWith--;
}
};

class Trie {
Node *root;

public:
Trie() {
root = new Node(); // Initialize root node
}

void insert(string &word) {
Node *node = root;
for (char ch : word) {
if (!node->contains(ch)) {
node->put(ch, new Node());
}
node = node->get(ch);
node->increasePrefix(); // Increment prefix count at each node
}
node->increaseEnd(); // Mark end of word
}

int countWordsEqualTo(string &word) {
Node *node = root;
for (char ch : word) {
if (!node->contains(ch)) return 0;
node = node->get(ch);
}
return node->countEndWith;
}

int countWordsStartingWith(string &prefix) {
Node *node = root;
for (char ch : prefix) {
if (!node->contains(ch)) return 0;
node = node->get(ch);
}
return node->countPrefix;
}

void erase(string &word) {
Node *node = root;
for (char ch : word) {
if (!node->contains(ch)) return; // Word doesn't exist
node = node->get(ch);
node->decreasePrefix(); // Decrease prefix count
}
node->decreaseEnd(); // Unmark end of word
}
};


📝 How It Works​

  • Each node keeps:
    • countPrefix: how many words pass through this node.
    • countEndWith: how many words end at this node.
  • Insert: Traverse through the word, creating nodes as needed, incrementing countPrefix. Finally, increment countEndWith.
  • Search Equal: Traverse and check if each character exists. If so, return the countEndWith at the last node.
  • Search Prefix: Traverse prefix and return countPrefix at the last character.
  • Erase: Traverse and decrement countPrefix. After traversal, decrement countEndWith.

🧩 Key Idea​

Unlike a standard Trie, this version supports:

  • Counting how many times a word was inserted.
  • Counting how many words share the same prefix.
  • Deleting occurrences of a word without affecting other words.

⏱️ Time & Space Complexity​

OperationTime ComplexitySpace Complexity
Insert WordO(L)O(N × L)
Count Word Equal ToO(L)O(1)
Count Prefix WordsO(L)O(1)
Erase WordO(L)O(1)
  • L: Length of the word
  • N: Number of inserted unique words

⚠️ Edge Cases​

  • Inserting or erasing the same word multiple times.
  • Searching for a prefix that doesn't exist.
  • Deleting a word not present in the Trie.

💡 Other Approaches​

FeatureStandard TrieFrequency Trie (This)
Prefix search✅✅
Word existence check✅✅
Word frequency count❌✅
Prefix frequency count❌✅
Deletion support❌ (manual)✅


🛠️ Other Notes​

  • Great use-case in autocomplete systems, dictionary frequency tracking, and search engines.
  • Can be extended for uppercase/lowercase, digits, or Unicode by expanding the links[] array.
🚀 Level Up Your Engineering Mindset

Never Study in Isolation. Join Binary Dose.

Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚡
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

💡Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→