Longest Word In Dictionary Problem


Description

LeetCode Problem 720. Given a list of strings words representing an English dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order. If there is no answer, return the empty string.

All the strings in the input will only contain lowercase letters.

Example:

1
2
3
Input:  words = ["w","wo","wor","worl", "world"]
Output: "world"
Explanation: The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".


Solution

Brute Force Approach

A simple solution is to use the brute force approach.

We loop through every word in the dictionary. For each word, we loop through every prefix of the world and check whether that prefix of the word exists in the dictonary. Finally, we return the longest word that every prefix of the word exists in the dictionary.

The time complexity of this approach is O(n2m), where n is the length of the dictionary and m is the maximum length of the word in the dictionary. The space complexity is O(1).

Trie and Depth First Search Approach

We can use the data structure trie to store the dictionary and use depth first search to find the longest possible answer. Using the trie data structure can help us reduce the time complexity.

In every trie node, we use an array of length 26 to store possible next trie node, and a flag to indicate whether the trie node is the last letter of a word in the dictionary.

Suppose we have a dictionary of words like this, words = [“a”, “banana”, “app”, “appl”, “ap”, “apply”, “apple”, “bar”]. The trie structure we build looks like the following. If the node is an end of a word, there is a * next to it.

1
2
3
4
5
6
7
8
9
10
11
a*   b
|    |
p*   a
|    | \
p*   n  r*
|    |
l*   a
|    |
e*   n
     |
     a*

After we build the trie, we can use depth first search to find the longest word that every letter in that word is an end of a word (marked by * in the above) in the dictionary.

The time complexity can be reduced to O(sum(mi)), where mi is the length of a word in the dictionary. The space complexity is O(sum(mi)).


Sample C++ Code

This is a C++ implementation of the trie and depth first search approach.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct TrieNode {
    TrieNode* arr[26];
    bool is_end;
    TrieNode() {
        for (int i = 0; i < 26; i ++) arr[i] = NULL;
        is_end = false;
    }
};

void insert(TrieNode* root, string key) {
    TrieNode* curr = root;
    for (int i = 0; i < key.size(); i ++) {
        int idx = key[i] - 'a';
        if (curr->arr[idx] == NULL)
            curr->arr[idx] = new TrieNode();
        curr = curr->arr[idx];
    }
    curr->is_end = true;
}


void dfs(TrieNode* root, string key, string& ans) {
    if (root == NULL) return;
    for (int i = 0; i < 26; i ++) {
        if (root->arr[i] != NULL) {
            if (root->arr[i]->is_end == true) {
                key += (char)(i) + 'a';
                if (key.size() > ans.size())
                    ans = key;
                else if (key.size() == ans.size()) {
                    if (key < ans)
                        ans = key;
                }
                dfs(root->arr[i], key, ans);
                key.pop_back();
            }
        }
    }
}

string longestWord(vector<string>& words) {
    TrieNode* root = new TrieNode();
    for (int i = 0; i < words.size(); i ++)
        insert(root, words[i]);
    string ans;
    dfs(root, "", ans);
    return ans;
}

int main() {
    vector<string> words = {"w","wo","wor","worl", "world"};
    cout << longestWord(words) << endl;
}




Related Posts

Map Sum Pairs Problem

LeetCode 677. Design a map that allows you to do...

Palindrome Pairs Problem

LeetCode 336. Given a list of unique words, return all...

Design Add And Search Words Data Structure Problem

LeetCode 211. Design a data structure that supports adding new...

Word Break Problem

LeetCode 139. Given a string s and a dictionary of...

Word Break II Problem

LeetCode 140. Given a string s and a dictionary of...

Stream of Characters Problem

LeetCode 1032. Implement the StreamChecker class as follows. Constructor, initialize...