LeetCode 720. 词典中最长的单词
方法一:暴力哈希
存储每个单词哈希表中,检查每一个单词前缀是否都出现过,返回字典序最小长度最长的单词
时间复杂度: O ( n ∗ 30 ) O(n*30) O(n∗30)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n∗30)
class Solution {
public:
set<string> S;
string ans;
bool check(string str) {
for (int i = 1; i < str.size(); i ++ )
if (!S.count(str.substr(0, i)))
return false;
return true;
}
string longestWord(vector<string>& words) {
for (auto& s : words)
S.insert(s);
for (auto& s : words)
if (check(s)) {
if (ans.size() < s.size()) ans = s;
else if (ans.size() == s.size() && ans > s) ans = s;
}
return ans;
}
};
方法二:排序+哈希
时间复杂度: O ( n ∗ 30 ∗ l o g n ) O(n*30*logn) O(n∗30∗logn)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n∗30)
class Solution {
public:
string longestWord(vector<string>& words) {
sort(words.begin(), words.end(), [](const string & a, const string & b) {
if (a.size() != b.size()) {
return a.size() < b.size();
} else {
return a > b;
}
});
string ans = "";
unordered_set<string> cnt;
cnt.insert("");
for (auto & word : words) {
if (cnt.count(word.substr(0, word.size() - 1))) {
cnt.insert(word);
ans = word;
}
}
return ans;
}
};
方法三:字典树
通过标记每一个结点id,遍历字典树找到有标记的最长的路径就是答案。
时间复杂度: O ( n ∗ 30 ) O(n*30) O(n∗30)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n∗30)
const int N = 30010;
int son[N][26], idx;
int id[N];
class Solution {
public:
void insert(string& str, int k) {
int p = 0;
for (auto c: str) {
int u = c - 'a';
if (!son[p][u]) son[p][u] = ++ idx;
p = son[p][u];
}
id[p] = k;
}
vector<int> dfs(int p, int len) {
vector<int> res{len, id[p]};
for (int i = 0; i < 26; i ++ ) {
int j = son[p][i];
if (j && id[j] != -1) {
auto t = dfs(j, len + 1);
if (res[0] < t[0]) res = t;
}
}
return res;
}
string longestWord(vector<string>& words) {
memset(id, -1, sizeof id);
memset(son, 0, sizeof son);
idx = 0;
for (int i = 0; i < words.size(); i ++ ) insert(words[i], i);
auto t = dfs(0, 0);
if (t[1] != -1) return words[t[1]];
return "";
}
};