BackhardTrie

Optimized Prefix Repository Solution

Problem Statement

Design a data structure to store and manage a collection of strings, supporting two primary operations: adding a string to the repository and retrieving the lexicographically smallest prefix of a given length that exists in the repository. If no such prefix exists for the specified length, the retrieval operation should return an empty string.

Example 1
Input
repository = { 'app', 'apple', 'application' }, length = 3
Output
app

Explanation: Step 1: We start by iterating over each string in the repository. We find the first string 'app' that has a length of 3 or more. Step 2: We then return the lexicographically smallest prefix of 'app' of length 3, which is 'app'.

Example 2
Input
repository = { 'app', 'apple', 'application' }, length = 4
Output

Explanation: Step 1: We start by iterating over each string in the repository. We find that there is no string with a length of 4 or more. Step 2: We then return an empty string because the problem statement asks for the lexicographically smallest prefix of length 4, but there is no such prefix.

Constraints

  • The total number of strings added to the repository will not exceed 10^5.
  • The total length of all strings added will not exceed 10^6 characters.
  • Each retrieval operation should be performed in reasonable time complexity, e.g., O(n) or better where n is the length of the strings or the given length.
  • The repository is initially empty.
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Optimized Prefix Repository — Problem Statement & Solution Guide

TrieHardMin Stack
TimeO(n * m)
|
SpaceO(n * m)

Problem Description

Design a data structure to store and manage a collection of strings, supporting two primary operations: adding a string to the repository and retrieving the lexicographically smallest prefix of a given length that exists in the repository. If no such prefix exists for the specified length, the retrieval operation should return an empty string.

Examples

Example 1

Input

repository = { 'app', 'apple', 'application' }, length = 3

Output

app

Explanation: Step 1: We start by iterating over each string in the repository. We find the first string 'app' that has a length of 3 or more. Step 2: We then return the lexicographically smallest prefix of 'app' of length 3, which is 'app'.

Example 2

Input

repository = { 'app', 'apple', 'application' }, length = 4

Output

Explanation: Step 1: We start by iterating over each string in the repository. We find that there is no string with a length of 4 or more. Step 2: We then return an empty string because the problem statement asks for the lexicographically smallest prefix of length 4, but there is no such prefix.

Constraints

  • The total number of strings added to the repository will not exceed 10^5.
  • The total length of all strings added will not exceed 10^6 characters.
  • Each retrieval operation should be performed in reasonable time complexity, e.g., O(n) or better where n is the length of the strings or the given length.
  • The repository is initially empty.

Optimal Approach & Strategy

An optimized approach involves using a Trie data structure to store the strings and then performing a depth-first search to find the lexicographically smallest prefix of a given length. This approach allows for efficient storage and retrieval of prefixes. The time complexity for adding a string and retrieving a prefix can be significantly improved.

Brute Force Approach

A brute force approach would involve storing all the strings in an array and then, for each retrieval operation, iterating over all strings to find the lexicographically smallest prefix of the given length. This approach would be inefficient and not scalable for large inputs. The time complexity would be high due to the nested loops. A more optimized approach is needed for better performance.

Verified Code Solutions

JavaScript Solution
Time: O(n * m)
class TrieNode {
    constructor() {
        this.children = new Map();
        this.isEndOfWord = false;
    }
}

class Trie {
    constructor() {
        this.root = new TrieNode();
    }

    addWord(word) {
        let node = this.root;
        for (let char of word) {
            if (!node.children.has(char)) {
                node.children.set(char, new TrieNode());
            }
            node = node.children.get(char);
        }
        node.isEndOfWord = true;
    }

    getSmallestPrefix(length) {
        let node = this.root;
        let prefix = '';
        for (let i = 0; i < length; i++) {
            if (node.children.size === 0) {
                return prefix;
            }
            let chars = Array.from(node.children.keys()).sort();
            prefix += chars[0];
            node = node.children.get(chars[0]);
        }
        return prefix;
    }
}

function solution(words, length) {
    let trie = new Trie();
    for (let word of words) {
        trie.addWord(word);
    }
    return trie.getSmallestPrefix(length);
}

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.