当前位置: 首页 > article >正文

前缀树学习

前缀树学习

1.长什么样子

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.重要的组成部分

class Trie {
    private Trie[] children;
    private boolean isEnd;

    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }
}

假如我们只构建一个只有26个英文小写字母的前缀树

那么children的长度就是26 ,如果children[i] 不为空,那么证明有某个单词使用了这个前缀

3.插入方法

    public void insert(String word) {
        Trie node = this;
        for(int i = 0;i<word.length();i++){
            char ch = word.charAt(i);
            int index = ch-'a';
            if(node.children[index]==null){
                node.children[index] = new Trie();
            }
            node = node.children[index];
        }
        node.isEnd = true;
    }

1.从root节点开始->计算单词索引->插入到children的正确位置上->改变指针

遍历完成后,记得加上一个标识证明这里是一个结尾

4.搜索方法

private Trie searchPrefix(String prefix){
        Trie node = this;
        for(int i = 0;i<prefix.length();i++){
            char ch = prefix.charAt(i);
            int index = ch-'a';
            if(node.children[index]==null){
                return null;
            }
            node = node.children[index];
        }
        return node;
    }

搜索前缀的方法,差不多是插入方法的逆向思路

如果我们要找到某个单词,只用判断isEnd,或者判断是否存在某个前缀,只有判断是否为null

   public boolean search(String word) {
        Trie node = searchPrefix(word);
        return node!=null && node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        return searchPrefix(prefix)!=null;
    }

5.leetcode题目练习

208. 实现 Trie (前缀树) | 力扣 | LeetCode | 🟠

上文的前缀树的实现就是这题

648. 单词替换 | 力扣 | LeetCode | 🟠

可以先把字典构建一个前缀树

我们需要对搜索方法进行一个小小的修改

对于每个单词,需要进行替换,那么可以先创建一个StringBuilder

对该单词的每个字符,进行前缀树匹配,匹配上了,sb就append,然后移动前缀树指针,如果有某个字符匹配不上,直接返回单词原型

如果前缀树已经到了末尾,返回sb即可

211. 添加与搜索单词 - 数据结构设计 | 力扣 | LeetCode | 🟠

其实这里需要注意的就是通配符的处理

对于没有通配符,和上面正常搜索就行

有通配符,需要遍历每一个children 相当于就是dfs

677. 键值映射 | 力扣 | LeetCode | 🟠

这题,需要加一个字段也就是int val;代表值

首先根据searchPrefix方法找到前缀

然后计算和,计算代码如下

 public int prefixSum(Trie prefix){
        int sum = prefix.isEnd ? prefix.val : 0;
        for(int i = 0;i<26;i++){
            Trie child = prefix.children[i];
            if(child!=null){
                sum +=prefixSum(child);
            }
        }
        return sum;
    }
        if(child!=null){
            sum +=prefixSum(child);
        }
    }
    return sum;
}


http://www.kler.cn/a/599957.html

相关文章:

  • 深入理解 HTML5 Web Workers:提升网页性能的关键技术解析
  • NO.56|基础算法-模拟|多项式输出|蛇形方阵|字符串的展开|方向向量(C++)
  • 《HarmonyOS Next自定义TabBar页签凸起和凹陷案例与代码》
  • 蓝桥杯—草坪(模拟+bfs分层处理)
  • 【计算机网络运输层详解】
  • 常见框架漏洞—Spring
  • 深度学习篇---PaddleDetectionPaddleOCR
  • 《AI大模型趣味实战 》第7集:多端适配 个人新闻头条 基于大模型和RSS聚合打造个人新闻电台(Flask WEB版) 1
  • Spring Boot - 动态编译 Java 类并实现热加载
  • 自动驾驶背后的数学:ReLU,Sigmoid, Leaky ReLU, PReLU,Swish等激活函数解析
  • 深度强化学习中的深度神经网络优化策略:挑战与解决方案
  • Spring Boot 一个接口实现任意表的 Excel 导入导出
  • Unity图形学Shader快速回顾
  • 如何从后端实现页面跳转?
  • 【区块链通用服务平台及组件】绿信链 | FISCO BCOS 应用案例
  • Python(4)Python函数编程性能优化全指南:从基础语法到并发调优
  • 数据结构---最小生成树
  • 3.23学习总结
  • C#基础学习(四)笑谈C#函数:从“Hello World”到“千变万化”的奇幻之旅
  • Delta Lake 解析:架构、数据处理流程与最佳实践