力扣面试150题--实现Trie(前缀树)

Day 67

题目描述

思路

初次思路 :此时还不了解什么是前缀树,尝试自己实现一下

由于我们需要快速定位前缀和字符串,于是我想到了使用hashset实现,tes用于存放字符串,prefixs存放前缀,获取前缀通过使用substring进行拆分。

java 复制代码
class Trie {
    Set<String>tes;
    Set<String>prefixs;
    public Trie() {
        tes=new HashSet<String>();
        prefixs=new HashSet<String>();
        num=new ArrayList<String>();
    }
    
    public void insert(String word) {
        if(tes.contains(word)){
            return;
        }
        else{
            tes.add(word);
            for(int i=0;i<=word.length();i++){
                String a=word.substring(0,i);
                prefixs.add(a);
            }
        }
    }
    
    public boolean search(String word) {
        return tes.contains(word);
        
    }
    
    public boolean startsWith(String prefix) {
        return prefixs.contains(prefix);
    }
}

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

学习前缀树后 :

前缀树的作用在于快速检索字符串的前缀,插入一个字符串,即为从根一次插入孩子节点,将字符串最后一个字符对应的节点标记结束节点,再插入另外一个相同前缀但最后n个字符不一样的字符串,那么在相同前缀的部分,不需要插入新的节点,直到第一个不同的字符,添加一个新的子节点。

这样做的好处,我们如果要获取两个字符串的前缀,只需要从根节点向下遍历,比较两个字符串,只要到某个节点出现了分支,则这个节点之前的节点就是两个字符的公共前缀。同时节约了存储空间

做法如下:

java 复制代码
class Trie {
    public Trie[]child;//孩子节点,可能插入的是26个英文字母中的一个
    public boolean isend;//判断是否为一个字符串的结束 区分前缀和字符串
    public Trie() {
        child=new Trie[26];
        isend=false;
    }
    
    public void insert(String word) {
        Trie node=this;//根节点
        for(int i=0;i<word.length();i++){
            char a=word.charAt(i);
            int index=a-'a';//转化为序号
            if(node.child[index]==null){
                node.child[index]=new Trie();//创建为新孩子
            }
            node=node.child[index];//移动到下一个孩子
        }
        node.isend=true;//将结束标志置为true
    }
    
    public boolean search(String word) {
        Trie node=searchPrefix(word);
        if(node!=null&&node.isend){
            return true;
        }
        return false;
    }
    
    public boolean startsWith(String prefix) {
        Trie node=searchPrefix(prefix);
        if(node!=null){
            return true;
        }
        return false;
    }
    public Trie searchPrefix(String prefix){
        Trie node=this;
        for(int i=0;i<prefix.length();i++){
            char a=prefix.charAt(i);
            int index=a-'a';
            if(node.child[index]==null){//还没遍历完前缀就结束了 说明找不到
                return null;
            }
            node=node.child[index];
        }
        return node;
    }
}

/**
 * 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);
 */
相关推荐
Navigator_Z4 分钟前
LeetCode //C - 1313. Decompress Run-Length Encoded List
c语言·算法·leetcode
秋饼5 分钟前
Redis 全面解析:从数据结构到主从/哨兵/集群、分布式锁与面试高频考点,代码到原理一次讲透
数据库·redis·分布式·面试·后端开发
Nuanyt1 小时前
LeetCode Hot 100 链表专题(四)· 3 题(Java)
java·算法·leetcode·链表·双指针
考研保研资料分享5 小时前
2022双非保研华科热能工程:三校考核、传热题与报名复盘
面试
weixin_3077791311 小时前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
nice_lcj52012 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
圣保罗的大教堂13 小时前
leetcode 453. 最小操作次数使数组元素相等 中等
leetcode
D e re k ZH15 小时前
C++ 并发、未定义行为与工程化难点(No 3)
数据结构·c++·算法·面试
Tisfy17 小时前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
君万17 小时前
【LeetCode每日一题】回溯:46. 全排列 78. 子集 39. 组合总和
算法·leetcode·go