美文网首页
208:前缀树

208:前缀树

作者: nobigogle | 来源:发表于2022-04-03 09:23 被阅读0次

    题意

    Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

    请你实现 Trie 类:

    Trie() 初始化前缀树对象。
    void insert(String word) 向前缀树中插入字符串 word。
    boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false。
    boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix,返回 true;否则,返回 false。

    分析

    前缀树是一种树形结构,其将一个字符串表示在一棵树中,例如:


    绘图1.png

    其中保存了数据【APP、APPLE、TIRE】其中,黄色节点表示含有这个对象,蓝色表示只是路径节点。
    注意:前缀树是有一个总的虚拟头节点。

    题解

    // 定义节点结构
    class TireNode {
        char value;// 当前节点的值
        boolean isExists = false;// 当前节点是都被包含【上述黄色节点】
        HashMap<Character, TireNode> children = new HashMap<Character, TireNode>();//【具体的分支】
    
        public TireNode(char value) {
            this.value = value;
        }
    }
    // 实现前缀树
    class Trie {
        // 虚拟头节点
        TireNode dummyHead = new TireNode('-');
    
        public void insert(String word) {
            // 处理特殊情况
            if (word == null || word.length() == 0) return;
            // 是否需要创建根节点
            insertSub(word, 0, dummyHead.children);
        }
    
        // 将指定元素插入前缀树的指定位置
        public void insertSub(String word, int start, HashMap<Character, TireNode> children) {
            // 插入到元素末尾,直接返回
            if (start == word.length()) return;
    
            if (children.containsKey(word.charAt(start))) {
                TireNode tireNodeTemp = children.get(word.charAt(start));
                // 判断是否存在当前元素
                if (start == word.length() - 1) tireNodeTemp.isExists = true;
                insertSub(word, start + 1, tireNodeTemp.children);
                // 不包含当前节点
            } else {
                TireNode node = new TireNode(word.charAt(start));
                // 判断是否存在当前元素
                if (start == word.length() - 1) node.isExists = true;
                children.put(word.charAt(start), node);
                // 插入元素
                insertSub(word, start + 1, node.children);
            }
        }
    
         // 查找特定字符串
        public boolean search(String word) {
            TireNode tireNodeResult = searchSub(word, 0, dummyHead.children.get(word.charAt(0)));
            if (tireNodeResult == null) return false;
            return tireNodeResult.isExists;
        }
    
    
        public TireNode searchSub(String word, int start, TireNode tireNode) {
            if (tireNode == null) return null;
            if (tireNode.value == word.charAt(start)) {
                if (start == word.length() - 1) return tireNode;
                // 寻找下一个字符
                if (start + 1 < word.length())
                    return searchSub(word, start + 1, tireNode.children.get(word.charAt(start + 1)));
            }
            return null;
        }
    
        // 是否有前缀
        public boolean startsWith(String prefix) {
            TireNode tireNodeResult = searchSub(prefix, 0, dummyHead.children.get(prefix.charAt(0)));
            if (tireNodeResult == null) return false;
            return true;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:208:前缀树

          本文链接:https://www.haomeiwen.com/subject/nhrndrtx.html