方法1 HashSet
class Solution {
public String longestWord(String[] words) {
String ans = "";
Set<String> set = new HashSet<>();
for (String s : words) set.add(s);
for (String s : set) {
int n = s.length(), m = ans.length();
if (n < m) continue;
if (n == m && s.compareTo(ans) > 0) continue;
boolean ok = true;
for (int i = 1; i <= n && ok; i++) {
String sub = s.substring(0, i);
if (!set.contains(sub)) ok = false;
}
if (ok) ans = s;
}
return ans;
}
}
语法:HashSet
set.contains(s.substring(0, i));
substring 左闭右开
方法2 字典树
Trie 树又叫「前缀树」或「字典树」
class Trie {
class TrieNode {
boolean end;
TrieNode[] tns = new TrieNode[26];
}
TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if (p.tns[u] == null) p.tns[u] = new TrieNode();
p = p.tns[u];
}
p.end = true;//记录下这个节点曾经作为过终点
}
public boolean search(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if (p.tns[u] == null) return false;
p = p.tns[u];
}
return p.end;
}
public boolean startsWith(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if (p.tns[u] == null) return false;
p = p.tns[u];
}
return true;
}
}
- 时间复杂度: Trie树的每次调用时间复杂度取决于入参字符串的长度。复杂度为O(Len) 。
- 空间复杂度:结点数量为 n ,字符集大小为 k 。复杂度为O(nk) 。