题目:
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.
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]
.思路:
1、哈希表法:我们定义一个哈希表,用来存储已找到所有前缀的字符串。然后对原来的字符串数组进行排序(这样每个字符串的前缀就会先于字符串本身被找出)。接着处理每一个字符串:如果该字符串的上一个前缀已经存在于哈希表中,则更新ret,并将该字符串也加入哈希表中。
算法的时间复杂度是O(nlogn),空间复杂度是O(n)。
2、字典树法:基本思路和哈希表是一致的,只不过我们用字典树存储所有的字符串。在对字符串数组进行排序之后,我们逐个检查字符串。只有当字符串的最大前缀已经存在于字典树中,我们才将该字符串加入字典树中,并更新ret。
代码:
1、哈希表法:
class Solution { public: string longestWord(vector<string>& words) { unordered_set<string> hash; hash.insert(""); sort(words.begin(), words.end()); string ret; for (auto s : words) { if(hash.count(s.substr(0, s.length() - 1)) > 0) { if (s.length() > ret.length()) { ret = s; } hash.insert(s); } } return ret; } };
2、字典树法:
class Solution { public: string longestWord(vector<string>& words) { root = new TrieNode(); string ret; sort(words.begin(), words.end()); for (auto &s : words) { TrieNode *node = root; int i = 0; for (; i + 1 < s.length(); ++i) { int index = s[i] - 'a'; if (node->children[index] == NULL) { break; } node = node->children[index]; } if (i + 1 == s.length()) { int index = s[i] - 'a'; node->children[index] = new TrieNode(); node = node->children[index]; if (ret.length() < s.length()) { ret = s; } } } return ret; } private: struct TrieNode { vector<TrieNode*> children; TrieNode() { children = vector<TrieNode*>(26, NULL); } }; TrieNode* root; };