力扣面试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);
 */
相关推荐
yaoh.wang18 小时前
力扣(LeetCode) 13: 罗马数字转整数 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
小小代码团21 小时前
2026 Office Online Server (全网最新/最详细/含问题修复) 终极部署教程
windows·microsoft·c#
sin_hielo21 小时前
leetcode 2110
数据结构·算法·leetcode
铭哥的编程日记21 小时前
后端面试通关笔记:从真题到思路(五)
面试·职场和发展
麦格芬2301 天前
LeetCode 763 划分字母区间
算法·leetcode·职场和发展
lzhdim1 天前
C#开发者必知的100个黑科技(前50)!从主构造函数到源生成器全面掌握
开发语言·科技·c#
前端一小卒1 天前
一个看似“送分”的需求为何翻车?——前端状态机实战指南
前端·javascript·面试
yong99901 天前
基于C#与三菱FX5U PLC实现以太网通信
网络·c#·php
xlp666hub1 天前
C进阶之内存对齐,硬件总线和高并发伪共享的底层原理
面试·代码规范
xhxxx1 天前
从被追问到被点赞:我靠“哨兵+快慢指针”展示了面试官真正想看的代码思维
javascript·算法·面试