题目描述
解题思路
前缀树的介绍
前缀树就是每一层都是比上一层多一个字母,没搜索一层,都是不同的前缀,但是使用了一个isEnd字段来表示该节点是否已经到了尾部,此时就不是前缀了,而是整个单词。(26子节点也是有hash映射的关系,所以根据字母很好定位在哪个子节点)
所以搜索的时候每层进行搜索,hash表定位子节点是否存在,再继续搜索,直到整个单词搜索完后都没有遇到null节点,表示前面的字符都出现了。
但是search函数搜索完之后需要检验isEnd是否为true,防止此整个单词不是整个单词而是别人的前缀字符串。
// 前缀树实现class Trie {class TrieNode {boolean isEnd = false;TrieNode[] next;public TrieNode() {this.isEnd = false;this.next = new TrieNode[26];}}TrieNode root;public Trie() {root = new TrieNode();}public void insert(String word) {TrieNode node = root;for (char c : word.toCharArray()) {// 如果前缀数没有构造过,那么就生成节点if (node.next[c - 'a'] == null) {node.next[c - 'a'] = new TrieNode();}// 移动到映射的节点继续构造node = node.next[c - 'a'];}// 整个单词构造完成之后,设置该节点isEnd为truenode.isEnd = true;}public boolean search(String word) {TrieNode node = root;for (char c : word.toCharArray()) {// 中间就匹配不了了,所以匹配不到最后节点if (node.next[c - 'a'] == null) {return false;}node = node.next[c - 'a'];}// word前面都匹配完了,如果最后一个节点isEnd是true,那么表示出现过该单词,而不是前缀return node.isEnd;}public boolean startsWith(String prefix) {TrieNode node = root;for (char c : prefix.toCharArray()) {// 中间就匹配不了了,所以匹配不到最后节点if (node.next[c - 'a'] == null) {return false;}node = node.next[c - 'a'];}// 不用管是否是最后一个单词,只要前面都匹配,就满足前缀return true;}}
自己瞎搞的,还过了…
class Trie {Set<String> trieSet;Set<String> preSet;public Trie() {trieSet = new HashSet<>();preSet = new HashSet<>();}public void insert(String word) {for (int i = 0; i < word.length() - 1; i++) {preSet.add(word.substring(0, i + 1));}trieSet.add(word);}public boolean search(String word) {return trieSet.contains(word);}public boolean startsWith(String prefix) {return preSet.contains(prefix);}}
