题目描述

image.png

解题思路

前缀树的介绍
前缀树就是每一层都是比上一层多一个字母,没搜索一层,都是不同的前缀,但是使用了一个isEnd字段来表示该节点是否已经到了尾部,此时就不是前缀了,而是整个单词。(26子节点也是有hash映射的关系,所以根据字母很好定位在哪个子节点)
208. 实现 Trie (前缀树) - 图2
所以搜索的时候每层进行搜索,hash表定位子节点是否存在,再继续搜索,直到整个单词搜索完后都没有遇到null节点,表示前面的字符都出现了。
但是search函数搜索完之后需要检验isEnd是否为true,防止此整个单词不是整个单词而是别人的前缀字符串。

  1. // 前缀树实现
  2. class Trie {
  3. class TrieNode {
  4. boolean isEnd = false;
  5. TrieNode[] next;
  6. public TrieNode() {
  7. this.isEnd = false;
  8. this.next = new TrieNode[26];
  9. }
  10. }
  11. TrieNode root;
  12. public Trie() {
  13. root = new TrieNode();
  14. }
  15. public void insert(String word) {
  16. TrieNode node = root;
  17. for (char c : word.toCharArray()) {
  18. // 如果前缀数没有构造过,那么就生成节点
  19. if (node.next[c - 'a'] == null) {
  20. node.next[c - 'a'] = new TrieNode();
  21. }
  22. // 移动到映射的节点继续构造
  23. node = node.next[c - 'a'];
  24. }
  25. // 整个单词构造完成之后,设置该节点isEnd为true
  26. node.isEnd = true;
  27. }
  28. public boolean search(String word) {
  29. TrieNode node = root;
  30. for (char c : word.toCharArray()) {
  31. // 中间就匹配不了了,所以匹配不到最后节点
  32. if (node.next[c - 'a'] == null) {
  33. return false;
  34. }
  35. node = node.next[c - 'a'];
  36. }
  37. // word前面都匹配完了,如果最后一个节点isEnd是true,那么表示出现过该单词,而不是前缀
  38. return node.isEnd;
  39. }
  40. public boolean startsWith(String prefix) {
  41. TrieNode node = root;
  42. for (char c : prefix.toCharArray()) {
  43. // 中间就匹配不了了,所以匹配不到最后节点
  44. if (node.next[c - 'a'] == null) {
  45. return false;
  46. }
  47. node = node.next[c - 'a'];
  48. }
  49. // 不用管是否是最后一个单词,只要前面都匹配,就满足前缀
  50. return true;
  51. }
  52. }

自己瞎搞的,还过了…

  1. class Trie {
  2. Set<String> trieSet;
  3. Set<String> preSet;
  4. public Trie() {
  5. trieSet = new HashSet<>();
  6. preSet = new HashSet<>();
  7. }
  8. public void insert(String word) {
  9. for (int i = 0; i < word.length() - 1; i++) {
  10. preSet.add(word.substring(0, i + 1));
  11. }
  12. trieSet.add(word);
  13. }
  14. public boolean search(String word) {
  15. return trieSet.contains(word);
  16. }
  17. public boolean startsWith(String prefix) {
  18. return preSet.contains(prefix);
  19. }
  20. }