方法1 HashSet

  1. class Solution {
  2. public String longestWord(String[] words) {
  3. String ans = "";
  4. Set<String> set = new HashSet<>();
  5. for (String s : words) set.add(s);
  6. for (String s : set) {
  7. int n = s.length(), m = ans.length();
  8. if (n < m) continue;
  9. if (n == m && s.compareTo(ans) > 0) continue;
  10. boolean ok = true;
  11. for (int i = 1; i <= n && ok; i++) {
  12. String sub = s.substring(0, i);
  13. if (!set.contains(sub)) ok = false;
  14. }
  15. if (ok) ans = s;
  16. }
  17. return ans;
  18. }
  19. }

语法:HashSet
set.contains(s.substring(0, i));
substring 左闭右开

方法2 字典树

Trie 树又叫「前缀树」或「字典树」

  1. class Trie {
  2. class TrieNode {
  3. boolean end;
  4. TrieNode[] tns = new TrieNode[26];
  5. }
  6. TrieNode root;
  7. public Trie() {
  8. root = new TrieNode();
  9. }
  10. public void insert(String s) {
  11. TrieNode p = root;
  12. for(int i = 0; i < s.length(); i++) {
  13. int u = s.charAt(i) - 'a';
  14. if (p.tns[u] == null) p.tns[u] = new TrieNode();
  15. p = p.tns[u];
  16. }
  17. p.end = true;//记录下这个节点曾经作为过终点
  18. }
  19. public boolean search(String s) {
  20. TrieNode p = root;
  21. for(int i = 0; i < s.length(); i++) {
  22. int u = s.charAt(i) - 'a';
  23. if (p.tns[u] == null) return false;
  24. p = p.tns[u];
  25. }
  26. return p.end;
  27. }
  28. public boolean startsWith(String s) {
  29. TrieNode p = root;
  30. for(int i = 0; i < s.length(); i++) {
  31. int u = s.charAt(i) - 'a';
  32. if (p.tns[u] == null) return false;
  33. p = p.tns[u];
  34. }
  35. return true;
  36. }
  37. }
  • 时间复杂度: Trie树的每次调用时间复杂度取决于入参字符串的长度。复杂度为O(Len) 。
  • 空间复杂度:结点数量为 n ,字符集大小为 k 。复杂度为O(nk) 。