Open In App

Strings from an array which are not prefix of any other string

Last Updated : 09 Nov, 2023
Comments
Improve
Suggest changes
7 Likes
Like
Report

Given an array arr[] of strings, the task is to print the strings from the array which are not prefix of any other string from the same array.
Examples: 
 

Input: arr[] = {“apple”, “app”, “there”, “the”, “like”} 
Output: 
apple 
like 
there 
Here “app” is a prefix of “apple” 
Hence, it is not printed and 
“the” is a prefix of “there”
Input: arr[] = {“a”, “aa”, “aaa”, “aaaa”} 
Output: 
aaaa 
 

 

Naive approach: For every string of the array, we check if it is prefix of any other string. If it is then don’t display it.
Efficient approach: We pick strings from array one by one and insert it into Trie. Then there are two cases for the insertion of the string: 
 

  1. While inserting if we found that the picked string is a prefix of an already inserted string then we don’t insert this string into the Trie.
  2. If a prefix is inserted first into the Trie and afterwards we find that the string is a prefix of some word then we simply make isEndOfWord = false for that particular node.

After constructing the Trie, we traverse it and display all the words in the Trie.
Below is the implementation of the above approach:
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
const int ALPHABET_SIZE = 26;
 
// Trie node
struct TrieNode {
    struct TrieNode* children[ALPHABET_SIZE];
 
    // isEndOfWord is true if the node represents
    // end of a word
    bool isEndOfWord;
};
 
// Returns new trie node (initialized to NULLs)
struct TrieNode* getNode(void)
{
    struct TrieNode* pNode = new TrieNode;
 
    pNode->isEndOfWord = false;
 
    for (int i = 0; i < ALPHABET_SIZE; i++)
        pNode->children[i] = NULL;
 
    return pNode;
}
 
// Function to insert a string into trie
void insert(struct TrieNode* root, string key)
{
    struct TrieNode* pCrawl = root;
 
    for (int i = 0; i < key.length(); i++) {
        int index = key[i] - 'a';
        if (!pCrawl->children[index])
            pCrawl->children[index] = getNode();
 
        // While inerting a word make
        // each isEndOfWord as false
        pCrawl->isEndOfWord = false;
        pCrawl = pCrawl->children[index];
    }
    int i;
 
    // Check if this word is prefix of
    // some already inserted word
    // If it is then don't insert this word
    for (i = 0; i < 26; i++) {
        if (pCrawl->children[i]) {
            break;
        }
    }
    // If present word is not prefix of
    // any other word then insert it
    if (i == 26) {
        pCrawl->isEndOfWord = true;
    }
}
 
// Function to display words in Trie
void display(struct TrieNode* root, char str[], int level)
{
    // If node is leaf node, it indicates end
    // of string, so a null character is added
    // and string is displayed
    if (root->isEndOfWord) {
        str[level] = '\0';
        cout << str << endl;
    }
 
    int i;
    for (i = 0; i < ALPHABET_SIZE; i++) {
 
        // If NON NULL child is found
        // add parent key to str and
        // call the display function recursively
        // for child node
        if (root->children[i]) {
            str[level] = i + 'a';
            display(root->children[i], str, level + 1);
        }
    }
}
 
// Driver code
int main()
{
    string keys[] = { "apple", "app", "there",
                      "the", "like" };
    int n = sizeof(keys) / sizeof(string);
 
    struct TrieNode* root = getNode();
 
    // Construct trie
    for (int i = 0; i < n; i++)
        insert(root, keys[i]);
 
    char str[100];
    display(root, str, 0);
 
    return 0;
}


Java

Python3

C#

Javascript

Output

apple
like
there


Time Complexity : Inserting all the words in the trie takes O(MN) time where-

N = Number of strings
M = Length of the largest string
Auxiliary Space : To store all the strings we need to allocate O(26*M*N) ~ O(MN) space for the Trie.

Approach#2: Using Brute Force

In this approach, we will compare each string in the array with every other string to check whether it is a prefix of any other string. If a string is not a prefix of any other string, we will add it to the output list.

Algorithm

1. Initialize an empty list output to hold the non-prefix strings.
2. Loop through each string in the input array arr.
3. For each string, check if it is a prefix of any other string in the array by looping through the array again and using the startswith() method.
4. If the string is not a prefix of any other string, add it to the output list.
5. Once all strings in the input array have been checked, return the output list containing only the non-prefix strings.

C++




#include <iostream>
#include <vector>
#include <string>
 
using namespace std;
 
// Function to find non-prefix strings
vector<string> nonPrefixStrings(const vector<string>& arr) {
    vector<string> output;
 
    for (int i = 0; i < arr.size(); i++) {
        bool isPrefix = false;
 
        for (int j = 0; j < arr.size(); j++) {
            if (i != j && arr[j].find(arr[i]) == 0) {
                // Check if arr[j] starts with arr[i]
                isPrefix = true;
                break;
            }
        }
 
        if (!isPrefix) {
            output.push_back(arr[i]);
        }
    }
 
    return output;
}
 
int main() {
    vector<string> arr = {"apple", "app", "there", "the", "like"};
    vector<string> result = nonPrefixStrings(arr);
 
    //cout << "Non-prefix strings in the array: ";
    for (const string& str : result) {
        cout << str << " ";
    }
 
    return 0;
}


Java

Python3

C#

Javascript

Output

['apple', 'there', 'like']


Time complexity: O(n^2), where n is length of array
Auxiliary Space: O(n), where n is length of array



Next Article

Similar Reads