1. 程式人生 > >[LeetCode][720] Longest Word in Dictionary

[LeetCode][720] Longest Word in Dictionary

[LeetCode][720] Longest Word in Dictionary題解


標籤:tire / hash / 剪枝

題意:找到最長的單詞,該單詞要在陣列中擁有一個字首,滿足該字首也是在陣列中。如果有相同長度返回字典序小的。也就是返回最長的字典序最小的字串。

這裡我們使用了字首樹資料結構。
首先對陣列進行排序,排序規則為長的在前面,如果相同長度,字典序小的在前面。
對於一組字串,把遍歷加入到字首樹中。
然後,對排序過後的vector<string>陣列進行遍歷,如果找到一個單詞在字首樹中有字首則返回該單詞。

核心程式碼:

bool startsWith(string prefix)
    {
        TrieNode *p = root;
        for (auto &a : prefix)
        {
            int i = a - 'a';
            if (!p->child[i])
            {
                return false;
            }
            p = p->child[i];
            if (!p->isWord)
            {
                return false;
            }
        }
        //如果是加入了單詞則需要判斷是不是被標記為isword
        //這裡是找是不是字首因此不需要標記isword
        return true;
    }

思路參考自:https://zxi.mytechroad.com/blog/string/leetcode-720-longest-word-in-dictionary/

AC程式碼

/*
 * [720] Longest Word in Dictionary
 *
 * https://leetcode.com/problems/longest-word-in-dictionary/description/
 *
 * algorithms
 * Easy (42.29%)
 * Total Accepted:    23.7K
 * Total Submissions: 56K
 * Testcase Example:  '["w","wo","wor","worl","world"]'
 *
 * 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.
 *
 * Example 1:
 *
 * 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".
 *
 *
 *
 * Example 2:
 *
 * Input:
 * words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
 * Output: "apple"
 * Explanation:
 * Both "apply" and "apple" can be built from other words in the dictionary.
 * However, "apple" is lexicographically smaller than "apply".
 *
 *
 *
 * Note:
 * All the strings in the input will only contain lowercase letters.
 * The length of words will be in the range [1, 1000].
 * The length of words[i] will be in the range [1, 30].
 *
 */
class TrieNode { public: TrieNode *child[26]; bool isWord; TrieNode() : isWord(false) { for (auto &a : child) { a = NULL; } } }; class Trie { private: TrieNode *root; public: // 1、對每個結點開一個字母集大小的陣列,對應的下標是兒子所表示的字母, // 內容則是這個兒子對應在大陣列上的位置,即標號;
// 2、對每個結點掛一個連結串列,按一定順序記錄每個兒子是誰; // 3、使用左兒子右兄弟表示法記錄這棵樹。 /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } /** Inserts a word into the trie. */ void insert(string word) { TrieNode *p = root; for (auto &a : word) { int i = a - 'a'; if (!p->child[i]) { p->child[i] = new TrieNode(); } p = p->child[i]; } //退出時候已經達到樹的末尾 p->isWord = true; } /** Returns if the word is in the trie. */ bool search(string word) { TrieNode *p = root; for (auto &a : word) { int i = a - 'a'; if (!p->child[i]) { return false; } p = p->child[i]; } return p->isWord; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { TrieNode *p = root; for (auto &a : prefix) { int i = a - 'a'; if (!p->child[i]) { return false; } p = p->child[i]; if (!p->isWord) { return false; } } //如果是加入了單詞則需要判斷是不是被標記為isword //這裡是找是不是字首因此不需要標記isword return true; } }; class Solution { public: string longestWord(vector<string> &words) { std::sort(words.begin(), words.end(), [](const string &w1, const string &w2) { if (w1.length() != w2.length()) return w1.length() > w2.length(); return w1 < w2; }); Trie trie; for (const string &word : words) { trie.insert(word); } for (const string &word : words) { if (trie.startsWith(word)) { return word; } } return ""; } };