trie图 java_【数据结构】之字典树(前缀树、Trie)_宁输输的博客-程序员宅基地

技术标签: trie图 java  

一、引言

字典树是专门为字符串处理设计的,字典树可以做到查询每个条目的时间复杂度和字段中一共有多少条目无关,跟查询的字符串长度相关。

1、什么是字典树

字典树结构

d7e225a50cc74c7e3ba303256ebdff93.png

说明:上图表示的是一颗只存英文单词的字典树,假设只包含小写英文字母,以上字典树中存储了6个单词,每个节点可以有26个指向下个节点的指针

二、实现

基于TreeMap实现字典树

import java.util.TreeMap;

/**

* 字典树、前缀树实现

*/

public class Trie {

/**

* 节点

*/

private class Node {

/**

* 是否是单词表示

*/

public boolean isWord;

/**

* 节点的子节点映射

*/

public TreeMap next;

public Node(boolean isWord) {

this.isWord = isWord;

next = new TreeMap<>();

}

public Node() {

this(false);

}

}

/**

* 根节点

*/

private Node root;

/**

* Trie树中存储的单词数量

*/

private int size;

/**

* 获取Trie中存储的单词数量

* @return

*/

public int getSize() {

return size;

}

/**

* 向Trie中添加一个新的单词Word

* @param word 单词

*/

public void add(String word) {

Node cur = root;

for (int i = 0; i < word.length(); i++) {

char c = word.charAt(i);

if (cur.next.get(c) == null) {

cur.next.put(c, new Node());

}

cur = cur.next.get(c);

}

if (!cur.isWord) {

cur.isWord = true;

size++;

}

}

/**

* 判断Trie中是否包含单词Word

* @param word 待查询单词

* @return

*/

public boolean contain(String word) {

Node cur = root;

for (int i = 0; i < word.length(); i++) {

char c = word.charAt(i);

if (cur.next.get(c) == null) {

return false;

}

cur = cur.next.get(c);

}

return cur.isWord;

}

/**

* 判断Trie中是否包含前缀prefix

* @param prefix

* @return

*/

public boolean isPrefix(String prefix) {

Node cur = root;

for (int i = 0; i < prefix.length(); i++) {

char c = prefix.charAt(i);

if (cur.next.get(c) == null) {

return false;

}

cur = cur.next.get(c);

}

return true;

}

}

三、字典树应用

1、力扣677号问题(键值映射)

问题描述:实现一个 MapSum 类里的两个方法,insert 和 sum。对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。

问题示例

输入: insert("apple", 3), 输出: Null

输入: sum("ap"), 输出: 3

输入: insert("app", 2), 输出: Null

输入: sum("ap"), 输出: 5

问题实现

import java.util.TreeMap;

/**

* Your MapSum object will be instantiated and called as such:

* MapSum obj = new MapSum();

* obj.insert(key,val);

* int param_2 = obj.sum(prefix);

*/

class MapSum {

/**

* 节点

*/

private class Node {

/**

* 单词结束节点保存的值

*/

public int value;

/**

* 节点的子节点映射

*/

public TreeMap next;

public Node(int value) {

this.value = value;

next = new TreeMap<>();

}

public Node() {

this(0);

}

}

/**

* 根节点

*/

private Node root;

/** Initialize your data structure here. */

public MapSum() {

root = new Node();

}

/**

* 向Trie树中插入单词及其值

* @param word 单词

* @param val 值

*/

public void insert(String word, int val) {

Node cur = root;

for (int i = 0; i < word.length(); i++) {

char c = word.charAt(i);

if (cur.next.get(c) == null) {

cur.next.put(c, new Node());

}

cur = cur.next.get(c);

}

cur.value = val;

}

/**

* 前缀求和

* @param prefix

* @return

*/

public int sum(String prefix) {

Node cur = root;

for (int i = 0; i < prefix.length(); i++) {

char c = prefix.charAt(i);

if (cur.next.get(c) == null) {

return 0;

}

cur = cur.next.get(c);

}

return sum(cur);

}

private int sum(Node node) {

int res = node.value;

for (Character c : node.next.keySet()) {

res += sum(node.next.get(c));

}

return res;

}

}

四、时间复杂度分析

1、基于TreeMap实现的字典树实现

添加单词操作:遍历待插入的单词,逐层插入各个字符与节点的映射,此操作与字典树中单词个数无关,与单词的字符长度有关,所以时间复杂度为O(w),w指单词字符长度。

查询单词操作:同添加单词操作,逐层遍历单词字符,时间复杂度为O(w),w指单词字符长度。

五、其它数据结构

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30316287/article/details/114843721

智能推荐

ffmpeg 录屏命令_ffmpeg录屏命令_越努力越幸运~的博客-程序员宅基地

window (安装dshow)ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264 -preset veryfast -crf 22 -tune:v zerolatency -pix_fmt yuv420p ..._ffmpeg录屏命令

opensuse kde桌面配置 ibus输入法_opensuse切换ibus_迈向虚无的博客-程序员宅基地

opensuse kde桌面配置 ibus输入法ibus 输入法介绍ibus-anthy: 一个日文输入法引擎,基于anthy。ibus-pinyin: 该软件暂时没有维护,而且最新的 ibus 引擎上部分功能不能使用。作为替代,请使用ibus-libpinyin。ibus-rime:一个强大的智能中文输入法,支持拼音、注音或者没有音调的拼音、双拼、粤拼、中州韵、仓颉和五笔86。_opensuse切换ibus

pytorch技巧 五: 自定义数据集 torch.utils.data.DataLoader 及Dataset的使用_pytorch torch.utils.data.dataloader dataset_董小姐~的博客-程序员宅基地

pytorch技巧 五: 自定义数据集 torch.utils.data.DataLoader 及Dataset的使用本博客中有可直接运行的例子,便于直观的理解,在torch环境中运行即可。1. 数据传递机制在 pytorch 中数据传递按一下顺序:创建 datasets ,也就是所需要读取的数据集。把 datasets 传入DataLoader。DataLoader迭代产生训练数据提供给模型。2. torch.utils.data.DatasetPytorch提供两种数据集: Map式_pytorch torch.utils.data.dataloader dataset

python --opencv图像处理Canny算子边缘检测(Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr 算子、 LOG 算子)_python opencv canny函数_像风一样的男人@的博客-程序员宅基地

图中我们可以看到, 100 与 90 之间相差的灰度值为 10 ,即当前像素点在 X 轴方向上的梯度为 10 ,而其它点均为 90 ,则求导后发现梯度全为 0 ,因此我们可以发现在数字图像处理,因其像素性质的特殊性,微积分在图像处理表现的形式为计算当前像素点沿偏微分方向的差值,所以实际的应用是不需要用到求导的,只需进行简单的加减运算。在说 Scharr 算子之前,必须要提的是前面我们介绍过的 Sobel 算子, Sobel 算子虽然可以有效的提取图像边缘,但是对图像中较弱的边缘提取效果较差。_python opencv canny函数

PaddleHub之《青春有你2》五人识别_《青春有你2》作业:五人识别_money哥的C的博客-程序员宅基地

好久没更新推文了。今天分享上次参加百度训练营的作业。主要是利用PaddleHub进行图像分类训练,然后识别。做的过程遇到问题比较多。比如路径问题,训练集和验证集制作,参数调优等。目录与训练数据参考:一、任务简介图像分类是计算机视觉的重要领域,它的目标是将图像分类到预定义的标签。近期,许多研究者提出很多不同种类的神经网络,并且极大的提升了分类算法的性能。本文以自己创建的数据集:青春有你2中选手识别为例子,介绍如何使用PaddleHub进行图像分类任务。#CPU环._《青春有你2》作业:五人识别

Windows本地安全策略_经典:本地用户以自己的身份验证怎么理解_煮酒笺华的博客-程序员宅基地

文章目录0x01 本地安全策略概述概念打开本地安全策略管理控制台0x02 账户策略密码策略1. 密码必须符合复杂性要求2. 密码长度最小值3. 密码最短使用期限4. 密码最长使用期限5. 强制密码历史6. 用可还原的加密来存储密码账户锁定策略1. 账户锁定时间2. 账户锁定阈值3. 重置账户锁定计数器0x03 本地策略审核策略用户权限分配安全选项0x01 本地安全策略概述概念​ 通过设置一系列的规则,影响当前计算机的安全设置,用户登录后会受安全策略的控制,从而保证本地计算机的安全。打开本地安全策略_经典:本地用户以自己的身份验证怎么理解

随便推点

英伟达驱动怎么设置显示帧数?_英伟达显卡右上角显示帧率 不适用_系统之家装机大师的博客-程序员宅基地

  很多玩家表示在游戏中显示帧数需要使用第三方工具,或者输入繁琐的控制台命令,很是麻烦,其实n卡驱动自带的GEFORCE ERPERIENCE其实是可以显示帧率的,但是很多人都不知道要怎么设置,接下来我们就一起来看看吧!Win11游戏专用系统下载_最新Win11游戏专用版系统下载V2022.03 - 系统之家  1、打开GEFORCE ERPERIENCE,最右边还有一个shadowplay按钮。点开。  2、点左边那个钮,就激活了shadowplay。  3、然后在首选项里选择shad_英伟达显卡右上角显示帧率 不适用

三国志战略版:Daniel_S7赤壁前瞻5_新武将战法解读_三国志战略版融合战法有哪些_大丹说三国的博客-程序员宅基地

一、蛇皮诸葛亮恕我直言,诸葛这个衣服,真的很居家,像套睡衣,让我想说一句“面料不错啊朋友”。我本以为是贴吧之前网曝图的那种,英姿飒爽,器宇轩昂的诸葛武侯。可能那张网曝图,未来会以SSP诸葛的形式出现吧(just kidding)。这个骚气的男人,再度拥有了一个同样骚气的战法。这个战法跟非SP版本相比,可以用四个字概括【转守为攻!】。【简约解读】诸葛亮:几率封住敌方2人主动战法,每次阻止造成100%伤害(智力+主将智力差)。SP诸葛亮:几率使友军1人自带主动,能立刻发动,只要触发就造成单体45_三国志战略版融合战法有哪些

Android中自定义折线图_android自定义折线图表_renkchina的博客-程序员宅基地

有时候,我们在做开发的时候,需要让用户更直观的看到数据变化,而又不应该给其提供一堆表格显示,有时候就需要用到,类似Excel中的图表,可是Google官方并没有提供自带的图表控件,这时候就需要我们自定义一个图表控件用于显示,我们想要的效果。(直接上图)如下: 先分析一下,效果图(忽略标题栏)。最上面是运动天数共31天,间隔一定距离向右偏移。向下是Y轴虚线图,数量点图标及折线趋势,最后做了一_android自定义折线图表

android入门级之资源的使用--声音资源--控件MediaPlayer_缎锦小妹的博客-程序员宅基地

最近刚学Android开发,看了51CTO学院的视频教程,感觉讲的非常详细,所以记下来便于以后查看。插入音频:首先在res文件夹下新建一个文件夹,命名为raw,把想放进去的音频拖进去,比如zuoer.mp3,切记命名格式,只能是小写字母a到z和数字0到9,下划线和点(首字母只能是下划线或字母)。然后就进入src文件夹下的MainActivity.Java文件了,声明MediaP

Launcher3之XmlPullParser解析Workspace默认配置过程分析_Code-Dreamer的博客-程序员宅基地

引入上一篇介绍了Workspace数据库和表的创建过程,本篇接着上一篇介绍下,workspace首次加载默认配置到数据库的过程。这个默认配置是什么呢?就是我们首次使用launcher的时候,桌面上默认显示应用图标、文件夹、小部件等元素的配置。在实际的项目中,需要按照需求去配置哪些应用图标需要显示,哪些需要隐藏,就是在这个默认配置文件中修改的,这个文件就是default_workspace.xm...

变阻抗控制理论基础、公式推导_变阻抗参数控制_茶花煮酒的博客-程序员宅基地

注:..代表省略了一些符号1、机器人建模:在人机交互环境中,机器人欧拉-拉普拉斯动态可以表示为:q关节角向量,M惯性矩阵,C向心力和科氏力扭矩,G重力向量,D粘性摩擦力,控制输入,环境力/交互力(contact)用弹簧-阻尼-质量系统来简化柔性机械臂,想象人与机械臂柔性交互。*机械臂动力学建模所使用的动力学方程一般有两种形式:欧拉-兰格朗日方程(E-L方程): ..._变阻抗参数控制

推荐文章

热门文章

相关标签