逐步解析力扣208. 实现 Trie (前缀树/字典树)

没看答案前随便写了下发现能过,但这完全是直接调轮子乱写

class Trie {
        Set<String> a = new HashSet<>();

        public Trie() {

        }

        public void insert(String word) {
            a.add(word);
        }

        public boolean search(String word) {
            return a.contains(word);
        }

        public boolean startsWith(String prefix) {
            for (String s:a) {
                if (s.startsWith(prefix)) return true;
            }
            return false;
        }
}

主要目的是要学习前缀树(字典树)

前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

时间复杂度:初始化为 O(1),其余操作为 O(∣S∣),其中 |S| 是每次插入或查询的字符串的长度

在这里插入图片描述
比用哈希表快了不少

在这里插入图片描述
其实看了代码之后就很好理解

class Trie {
        private Trie[] children;
        private boolean isEnd;

        public Trie() {
            children = new Trie[26];
            isEnd = false;
        }

        public void insert(String word) {
            Trie node = this;
            for (int i = 0; i < word.length(); i++) {
                char ch = word.charAt(i);
                int index = ch - 'a';
                if (node.children[index]==null) node.children[index] = new Trie();
                node = node.children[index];
            }
            node.isEnd = true;
        }

        public boolean search(String word) {
            Trie node = searchPrefix(word);
            return node !=null && node.isEnd;
        }
        private Trie searchPrefix(String prefix){
            Trie node = this;
            for (int i = 0; i < prefix.length(); i++) {
                char ch = prefix.charAt(i);
                int index = ch - 'a';
                if (node.children[index]==null) return null;
                node = node.children[index];
            }
            return node;
        }

        public boolean startsWith(String prefix) {
           return searchPrefix(prefix) !=null;
        }
    }

首先以数组形式声明一个n个子节点(基本以26个英文字母为最大长度)
private Trie[] children;

和一个字符串结尾
private boolean isEnd;

构造的时候声明26个英文字母和为false的结尾

在这里插入图片描述

开始新增
在这里插入图片描述
把当前类作为node节点,开始遍历传进来的word字符串,字符-‘a’获取他的数组位置
int index = ch - 'a';
在这里插入图片描述

然后记录在 children 数组的对应位置上
if (node.children[index]==null) node.children[index] = new Trie();

node跳到子节点继续遍历
node = node.children[index];

走完循环也就到头了,把isEnd置true
在这里插入图片描述
这时候就插入完成,一个完整的字典树就建好了

多个不同字符串也能进来,例如包含了三个单词 “sea”,“sells”,“she” 的 Trie结构如图
在这里插入图片描述
红色节点的isEnd就是true

新增没问题了,然后是search方法,他其实和startsWith方法类似,不同点在于node.isEnd的判断
在这里插入图片描述
看一下共同调用的方法searchPrefix,和insert方法几乎一样
在这里插入图片描述

区别在于遍历匹配节点的时候,如果不匹配,子节点肯定为null,因此返回null;否则返回完整的树结构。

之后走出该方法,判断null来区分该字符串到底是不是前缀了,不等于null表示匹配成功,等于null gg

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>