题目描述
给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。
若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。
示例 1:
输入:words = [“w”,“wo”,“wor”,“worl”, “world”]
输出:“world”
解释: 单词"world"可由"w", “wo”, “wor”, 和 "worl"逐步添加一个字母组成。
示例 2:
输入:words = [“a”, “banana”, “app”, “appl”, “ap”, “apply”, “apple”]
输出:“apple”
解释:“apply” 和 “apple” 都能由词典中的单词组成。但是 “apple” 的字典序小于 “apply”
提示:
1 <= words.length <= 1000
1 <= words[i].length <= 30
所有输入的字符串 words[i] 都只包含小写字母。
思路
主要用到字典树
代码
class Solution {
public:
string longestWord(vector<string>& words) {
sort(words.begin(), words.end());
Trie *pTrie = new Trie();
for (string word: words) {
pTrie->insert(word);
}
string ans = "";
int maxSize = 0;
for (string word: words) {
if (word.size() > maxSize && pTrie->search(word)) {
ans = word;
maxSize = ans.size();
}
}
return ans;
}
private:
class Trie {
public:
Trie(): root(new TrieNode()) {}
void insert(string &word) {
TrieNode *p = root.get();
for (char &c: word) {
if (nullptr == p->childs[c]) {
p->childs[c] = new TrieNode();
}
p = p->childs[c];
}
p->is_word = true;
}
bool search (string &word) {
TrieNode *p = root.get();
for (char &c: word) {
p = p->childs[c];
//每个前缀都出现在了字典树中
if (!p->is_word) {
return false;
}
}
return true;
}
private:
struct TrieNode {
TrieNode (): is_word(false) {};
~TrieNode() {
for (auto child: childs) {
if (child.second) { delete child.second;}
}
};
bool is_word;
map<char, TrieNode*> childs;
};
std::unique_ptr<TrieNode> root;
};
};