720. Longest Word in Dictionary*

​https://leetcode.com/problems/longest-word-in-dictionary/​

题目描述

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]​​.

C++ 实现 1

可以考虑先对字典进行排序, 规则是:

  • 长度小的排前面
  • 长度相等的, 但是字典序大的排前面

上述规则也可以倒过来, 比如(长度大的排前面, 同时长度相等的但字典序小的排前面).

然后从后向前遍历数组, 判断每个字符串是否能用其他字符串逐渐形成, 这一步使用哈希表完成. 从后向前, 当找到第一个满足条件的字符串, 直接返回即可.

class Solution {
private:
struct Comp {
bool operator()(const string &s1, const string &s2) {
if (s1.size() < s2.size())
return true;
else if (s1.size() == s2.size())
return (s1 > s2);
return false;
}
};
public:
string longestWord(vector<string>& words) {
std::sort(words.begin(), words.end(), Comp());
unordered_set<string> record(words.begin(), words.end());

for (int i = words.size() - 1; i >= 0; --i) {
bool found = true;
for (int j = words[i].size() - 1; j > 0; j--)
if (!record.count(words[i].substr(0, j))) {
found = false;
break;
}
if (found)
return words[i];
}
return "";

}
};

C++ 实现 2

速度更慢一些, 不排序, 而是对哈希表中的每一个字符串, 判断是否能用其他字符串逐渐形成, 同时还要判断是否满足题目中的条件.

class Solution {
public:
string longestWord(vector<string>& words) {
unordered_set<string> record(words.begin(), words.end());
string res;
for (auto &p : record) {
if (p.size() >= res.size()) {
bool contains = true;
for (int i = 0; i < p.size(); ++ i) {
if (!record.count(p.substr(0, i + 1))) {
contains = false;
break;
}
}
if (contains) {
if (res.empty() || p.size() > res.size()) res = p;
else if (p.size() == res.size()) res = p < res ? p : res;
}
}
}
return res;
}
};