[LeetCode][720] Longest Word in Dictionary
阿新 • • 發佈:2018-11-11
[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 "";
}
};