图论----4.实现 Trie (前缀树)

题目链接

/**

        Trie前缀树基本结构:

                        (多叉单词查找树)每个Trie中包含一个Trie数组与一个结束标识

                        Trie[] children Trie数组,每个节点都可存放一个Trie,其索引代表该节点对应的字符。

                        boolean isEnd 结束标识, 代表当前节点是否是一个完整单词的结尾巴

        前缀树insert流程:

                        计算第一个字符的索引位置,判断根节点的Trie节点数组中是否已有该字符(对应位置不为null,有Trie节点)

                        若没有则创建新的节点赋值到对应位置,有则迭代Trie节点与字符按上述流程继续处理

                        按上述流程迭代字符与Trie节点,直到处理到最后一个字符,将isEnd设置为true

         前缀树search流程:

                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)

                        有则迭代字符与Trie节点,重复上述流程;无则返回false

                        直到迭代到最后一个字符,判断isEnd是否为true,若不为true也返回false(只是在某个单词中出现了相同的部分)

        前缀树startsWith流程:

                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)

                        有则迭代字符与Trie节点,重复上述流程;无则返回false

                        直到最后一个字符也存在(只判断有无该前缀,无需判断isEnd)

        可抽取的公共方法:(查找前缀)

                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)

                        有则迭代字符与Trie节点,重复上述流程; 返回最后一个节点

                        search搜寻到最后一个节点判断其isEnd即可

                        startsWith搜寻到最后一个节点判断是否为空即可

*/

class Trie {

    /**
        Trie前缀树基本结构:
                        (多叉单词查找树)每个Trie中包含一个Trie数组与一个结束标识
                        Trie[] children Trie数组,每个节点都可存放一个Trie,其索引代表该节点对应的字符。
                        boolean isEnd 结束标识, 代表当前节点是否是一个完整单词的结尾巴
        前缀树insert流程:
                        计算第一个字符的索引位置,判断根节点的Trie节点数组中是否已有该字符(对应位置不为null,有Trie节点)
                        若没有则创建新的节点赋值到对应位置,有则迭代Trie节点与字符按上述流程继续处理
                        按上述流程迭代字符与Trie节点,直到处理到最后一个字符,将isEnd设置为true
         前缀树search流程:
                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)
                        有则迭代字符与Trie节点,重复上述流程;无则返回false
                        直到迭代到最后一个字符,判断isEnd是否为true,若不为true也返回false(只是在某个单词中出现了相同的部分)
        前缀树startsWith流程:
                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)
                        有则迭代字符与Trie节点,重复上述流程;无则返回false
                        直到最后一个字符也存在(只判断有无该前缀,无需判断isEnd)
        可抽取的公共方法:(查找前缀)
                        计算第一个字符的索引位置,判断根节点的Trie节点数组是否已有该字符(对应位置不为null,有Trie节点)
                        有则迭代字符与Trie节点,重复上述流程; 返回最后一个节点
                        search搜寻到最后一个节点判断其isEnd即可
                        startsWith搜寻到最后一个节点判断是否为空即可
    */

    //节点数组
    private Trie[] children;
    //结束标识
    boolean isEnd;

    //公共方法
    private Trie searchPrefix(String prefix) {
        Trie node = this; //读取当前节点
        for(char ch : prefix.toCharArray()) {
            //计算当前字符索引位置
            int index = ch - 'a'; 
            //迭代
            node = node.children[index];
            if(node == null) { //若为空代表已中断直接结束即可
                break;
            }
        }
        return node;
    }

    public Trie() {
        children = new Trie[26]; //一共26个字符
        isEnd = false; //结束标识默认为false
    }
    

    public void insert(String word) {
        Trie node = this; //读取当前节点
        for(char ch : word.toCharArray()) {
            //计算当前字符索引位置
            int index = ch - 'a'; 

            //若当前节点的Trie节点数组中不存在该字符
            if(node.children[index] == null) {
                Trie son = new Trie();
                node.children[index] = son;
            }

            //迭代(存在则直接迭代)
            node = node.children[index]; 
        }
        node.isEnd = true; //设置结束标识
    }
    
    public boolean search(String word) {
        //一直读取到最后一个字符 判断isEnd即可
        Trie node = searchPrefix(word);
        if(node != null) {
            return node.isEnd;
        }
        return false; 
    }
    
    public boolean startsWith(String prefix) {
        //一直读取到最后一个字符 判断是否为空即可
        if(searchPrefix(prefix) != null) {
            return true;
        }

        return false;
        
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值