【LeetCode笔记】208. 实现Trie(前缀树)(Java、前缀树)

本文介绍了如何使用二十六叉树(Trie)数据结构来实现字符串的插入、搜索及判断是否以特定前缀开始的功能。核心在于TrieNode的使用,每个节点包含一个布尔标志isEnd表示是否为单词结尾,并通过字符数组next保存子节点。在插入过程中,确保不会丢失引用,搜索和前缀检查则遍历树直到遇到空节点或到达字符串末尾。
摘要由CSDN通过智能技术生成

题目描述

  • 属于那种,敲过一遍就不会忘了的那种题,就是学一个新的数据结构= =
  • 二十六叉树!
    在这里插入图片描述

思路 & 代码

  • isEnd 非常重要噢,只有正式 insert 了的单词才能被 search 到。
  • 在 Trie 中实现内部类 TrieNode
  • 说实话,insert、search、startWith 三个函数的结构都十分相似= =
  • 注意 new Node 的时候小心。。引用丢失就难受了
class Trie {
    private class TrieNode{
        boolean isEnd;
        TrieNode[] next;

        TrieNode(){
            isEnd = false;
            next = new TrieNode[26];
        }
    }

    private TrieNode root;

    /** Initialize your data structure here. */
    public Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    // 没则插,结尾改 true (出现了,但是没真正 insert 的话,不算:比如 insert apple , 然后 search app = false
    public void insert(String word) {
        char[] wordC = word.toCharArray();
        TrieNode nowNode = root;
        for(int i = 0; i < wordC.length; i++){
            // error:TrieNode nextNode = nowNode.next[wordC[i] - 'a']; nextNode = new TrieNode()
            // 会直接丢失引用!
            int index = wordC[i] - 'a';
            if(nowNode.next[index] == null){
                nowNode.next[index] = new TrieNode();
            }
            nowNode = nowNode.next[index];
        }
        // 结束,标志单词结尾字符
        nowNode.isEnd = true;
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        char[] wordC = word.toCharArray();
        TrieNode nowNode = root;
        for(int i = 0; i < wordC.length; i++){
            int index = wordC[i] - 'a';
            if(nowNode.next[index] == null){
                return false;
            }
            nowNode = nowNode.next[index];
        }
        return nowNode.isEnd;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
         char[] wordC = prefix.toCharArray();
        TrieNode nowNode = root;
        for(int i = 0; i < wordC.length; i++){
            int index = wordC[i] - 'a';
            if(nowNode.next[index] == null){
                return false;
            }
            nowNode = nowNode.next[index];
        }
        return true;
    }
}

/**
 * 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);
 */

更新版

  • 其实三个函数的代码都差不多= =
  • 前缀树:存储字符串的一种树结构(二十六叉树),可以实现拼写检查自动补全功能。
class Trie {
    TrieNode root;

    private class TrieNode {
        boolean isEnd;
        TrieNode[] nextNode;
        public TrieNode() {
            isEnd = false;
            nextNode = new TrieNode[26];
        }
    }

    public Trie() {
        root = new TrieNode();
    }
    
    public void insert(String word) {
        TrieNode nowNode = root;
        for(char c : word.toCharArray()) {
            int index = c - 'a';
            if(nowNode.nextNode[index] == null) {
                nowNode.nextNode[index] = new TrieNode();
            }
            nowNode = nowNode.nextNode[index];
        }
        nowNode.isEnd = true;
    }
    
    public boolean search(String word) {
        TrieNode nowNode = root;
        for(char c : word.toCharArray()) {
            int index = c - 'a';
            if(nowNode.nextNode[index] == null) {
                return false;
            }
            nowNode = nowNode.nextNode[index];
        }
        return nowNode.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        TrieNode nowNode = root;
        for(char c : prefix.toCharArray()) {
            int index = c - 'a';
            if(nowNode.nextNode[index] == null) {
                return false;
            }
            nowNode = nowNode.nextNode[index];
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值