Java中前缀树(Trie)的简介与使用 LeetCode 力扣 720 词典中最长的单词

java实现的Trie树数据结构 最近在学习的时候,经常看到使用Trie树数据结构来解决问题,比如“ 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。” 该如何解决? 有一种方案就是使用Trie树加 排序实现 。 什么是Trie 树呢?也就是常说的字典树,网上对此讲得也很多,简单补充一下个人理解: 它实际上相当于把单词的公共部分给拎出来,这样一层一层往上拎直 阅读详情

Trie树是一种特殊的N叉树,又称字典树,单词查找树,键树等。一般用于字符串的储存,查找,比较,偶尔也会用于删除。除根节点外,Trie树的每一个节点包含一个字符,每个节点的子节点字符不重复(但不同节点可以有相同的子节点,比如表示字符串“aa”和“ba”)。从根节点到某一节点的路径为该节点对应的字符串,因此每条路径上的字符排列应该是唯一的。

Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销,对字符串的查找通常效率高于哈希表。

画一棵前缀树:
在这里插入图片描述
可以看到前缀树的几个要点:

  1. 黄色的是根节点,通常不赋值,或赋特殊值。
  2. 节点所有的子节点都与该节点相关的字符串有着共同的前缀。
  3. 绿色的节点代表从根节点到该节点可形成存在的字符串,图中包含字符串"a",“d”,“kt”,“km”,“be”,“bed”,“bet”,“do”。而不以绿色节点为末端的路径和不以根节点开始的路径形成的字符串不存在。

如果要查询一个单词是否存在,我们只需要从根节点开始,沿着单词的每一个字符向前走。每个节点的子节点字符唯一,是不会走到岔路上的。走到最后一个字符时,只要看这个节点是否被标记为绿色就可以知道它是否存在。如果走着走着没有路了,也说明这个节点不存在。插入时,如果没有路则创造路,走到最后一个节点时,把这个节点标记为绿色,就完成了插入操作。这个过程所用时间为O(Length),Length为单词长度。

在这里插入图片描述

通常用数组或HashMap来储存前缀树。因为不知道树中存在哪些字符,因此需要为每个子节点声明大小为26的数组。数组中的查找速度更快,但当字符种类不多时,会造成空间的浪费。

class TrieNode {
    char ch;
    boolean valid;
    int[] children = new int[26];
    public TrieNode(char ch){
        this.ch = ch;
    }
}

另一种实现方法时使用HashMap:

class TrieNode {
    char ch;
    boolean valid;
    HashMap<Character, TrieNode> children = new HashMap();
    public TrieNode(char ch){
        this.ch = ch;
    }
}

children为TrieNode的子节点列表。键为字符,值为字符对应的节点。子节点的存取稍慢,但是因为可以按需插入map,能够节省空间,更加灵活。

除了节点值,子节点列表,在节点定义中还加入了一个布尔值,用来标记是否是有效的字符串(是否为绿色节点)。

前缀树的主要操作有插入和查找,构建前缀树的过程就是多次调用插入函数。

public class Trie {
    TrieNode root;
    Trie() {
        root = new TrieNode('0');
    }
    public void insert(String word) {
        TrieNode cur = root;
        for(char ch : word.toCharArray()) {
            cur.children.putIfAbsent(ch, new TrieNode(ch));
            cur = cur.children.get(ch);
        }
        cur.valid = true;
    }
}

类似地,实现查找功能:

	public boolean search(String word) {
        TrieNode cur = root;
        for(char ch : word.toCharArray()) {
            if(cur == null) break;
            cur = cur.children.get(ch);
        }
        return cur != null && cur.valid;
    }

LeetCode一道可以用前缀树解的题:

  1. 词典中最长的单词
    给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

示例 1:

输入:
words = [“w”,“wo”,“wor”,“worl”, “world”]
输出: “world”
解释:
单词"world"可由"w", “wo”, “wor”, 和 "worl"添加一个字母组成。

示例 2:

输入:
words = [“a”, “banana”, “app”, “appl”, “ap”, “apply”, “apple”]
输出: “apple”
解释:
“apply"和"apple"都能由词典中的单词组成。但是"apple"得字典序小于"apply”。

思路:
可以用给出的words数组中所有单词构建前缀树,再深搜遍历前缀树, 找到前缀都在树中的最长单词。

class Solution {    
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        int index = 0;
        for(String word : words)
            trie.insert(word, ++index);
        return trie.bfs(trie.root, words);
    }
}

class TrieNode {
    char ch;
    boolean valid;
    int index;
    Map<Character, TrieNode> children = new HashMap<>();
    TrieNode(char ch) {
        this.ch = ch;
    }
}

public class Trie {
    TrieNode root;

    Trie() {
        root = new TrieNode('0');
    }

    public void insert(String word, int index) {
        TrieNode cur = root;
        for(char ch : word.toCharArray()) {
            cur.children.putIfAbsent(ch, new TrieNode(ch));
            cur = cur.children.get(ch);
        }
        cur.index = index;
    }

    public String bfs (TrieNode root, String[] words) {
        String ans = "";
        Queue<TrieNode> queue = new LinkedList<>();
        TrieNode cur = root;
        queue.offer(root);
        while(!queue.isEmpty()) {
            cur = queue.remove();
            for(TrieNode node : cur.children.values()) {
                if (node.index > 0) {
                    String str = words[node.index - 1];
                    if (str.length() > ans.length() ||
                            (str.length() == ans.length() && str.compareTo(ans) < 0))
                        ans = str;
                    queue.offer(node);
                }
            }            
        }
        return ans;
    }
}
VXLAN技术详解 VXLAN(虚拟可扩展局域网)是一种Overlay二层虚拟化技术,通过MAC-in-UDP封装在IP网络上构建大规模虚拟二层网络。核心组件包括VTEP(隧道端点)、24位VNI(支持1600万个虚拟网络)和VXLAN网关。相比VLAN,VXLAN具有超大规模扩展、跨三层互联、支持虚拟机无缝迁移等优势,适用于云数据中心多租户隔离、跨数据中心互联等场景。其基于IP路由的封装方式无需改造物理网络,为现代云网络提供了弹性、安全的虚拟化解决方案。 阅读详情

相关推荐

如何从零开始写小程序

看了这篇文章,即使让我现在就从头写一个能够正常运行的小程序,也没有原本想象中的那么难了。 在本文中,我们将会以一个具体的小程序为例,带领大家从零到一完成一个小程序的开发流程,并将这个小程序上传到 FinClip.com 进行小程序提审与上架操作。 我们新建了一个叫做「HelloWorld」的小程序,FIDE 在初始化小程序项目时,会自动在项目目录中补充对应所需要的项目文件。那不妨让我们先从小程序目录下的配置文件开始,逐渐揭开小程序的面纱。 使用 FIDE 编辑小程序 1. 认识 json 文件 在小程序项目

POHOU23的博客 4395

Java实现字典树 Trie

字典树又称为前缀树,是n叉树的特殊形式,广泛应用于统计和排序大量的字符串,它可以很大程度减少无所谓的字符比较,查询效率较高,Trie的核心思想是空间换时间,利用字符串的公共前缀提高查询效率

m0_62701287的博客 2061

AIDC智算中心建设:资源池化核心技术解析

AI 应用的POD在运行的时候,通过池化运行时访问虚拟GPU、执行AI任务,池化运行时拦截对虚拟GPU的访问请求、转递给池化服务代理执行,池化服务代理通过向智算池化控制器查询虚拟GPU所对应的真实智算资源位置、规格,按查询结果分配智算资源、执行AI任务,如果真实的智算资源位于远程计算节点,则由本地池化服务代理将访问请求转递给远程计算节点上的池化服务代理处理,相关通信经由参数面网络。

u013891230的博客 2431

【java】208. 实现 Trie (前缀树)---用封装集合快速实现!!!

Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。 请你实现 Trie 类: Trie() 初始化前缀树对象。 void insert(String word) 向前缀树中插入字符串 word 。 boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。 boolean startsWith(S

惠菁 587

【强化学习】11 —— Double DQN算法与Dueling DQN算法

可以看到由于数据点的分布,使得拟合出的价值函数无法与真实的价值函数吻合,甚至在部分区域产生了明显的偏差。Dueling DQN 是 DQN 另一种的改进算法,它在传统 DQN 的基础上只进行了微小的改动,但却能大幅提升 DQN 的表现。这样,即使其中一套神经网络的某个动作存在比较严重的过高估计问题,由于另一套神经网络的存在,这个动作最终使用的值不会存在很大的过高估计问题。.在同一个状态下,所有动作的优势值之和为 0,因为所有动作的动作价值的期望就是这个状态的状态价值。环境的状态包括倒立摆角度的正弦值。

sinat_52032317的博客 1万+

避开SM30维护视图的坑:自动更新字段+日志记录的5个关键配置步骤

本文深入解析了SAP ABAP开发中SM30维护视图的深度定制,聚焦于实现自动更新字段与日志记录功能。文章详细阐述了从SE54配置起点到核心编码的5个关键步骤,重点讲解了如何利用事件驱动模型(如05创建事件和01保存前事件)安全操作动态数据结构,并提供了避免常见陷阱的实用技巧,帮助开发者构建稳定可靠的自动化维护机制。

plant的博客 622

Java实现 LeetCode 720 词典中最长的单词(字典树)

720. 词典中最长的单词 给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。 若无答案,则返回空字符串。 示例 1: 输入: words = [“w”,“wo”,“wor”,“worl”, “world”] 输出: “world” 解释: 单词"world"可由"w...

南 墙 1万+

【常见开源库的二次开发】基于openssl的加密与解密——openssl认识与配置(一)

OpenSSL 是一个开源的软件库,它提供了一系列加密工具和协议,主要用于实现安全通信,如在网络上的数据传输。它支持多种加密算法,包括对称加密、非对称加密、散列函数、伪随机数生成器、数字签名、密钥交换以及证书管理等。

嵌入式技术开发 4161

Java 前缀树Trie的实现

Trie的基础实现:本实现只适用于英语这么语言,将单词存放在Character对象中,所以Trie才没有使用泛型。 使用泛型是比较好的设计: 不过这里的应用场景为英语单词,所以这里不采用泛型。这里将单词看成字符串是由一个个Character组成的。 1.向Trie添加元素(非递归写法) import java.util.TreeMap; public class Trie { ...

抛弃幻想,准备斗争 1187

极智AI | 详解 ViT 算法实现

大家好,我是极智视界,本文详细介绍一下 ViT 算法的设计与实现,包括代码。

极智视界 5603

Claude Code 里的 MCP 连接失败到底在报什么

文档还说明,HTTP 类型、stdio 类型等 MCP server 的接入方式不同,stdio server 会被 Claude Code 当作本地进程拉起,而 HTTP server 则需要 Claude Code 去访问一个已经存在的 HTTP endpoint。把这段输出翻成更接地气的运维语言,就是 Claude Code 已经知道我们想接两个外部能力,一个是 SAP ADT 官方 MCP,一个是 Chrome DevTools MCP,但当前没有一个完成握手。,因为它的信号更明确。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 145

前缀树Trie及其应用(上) ---Leetcode208、Leetcode720

前缀树是一种很重要的数据结构,本篇文章将通过Leetcode中的两道与前缀树相关的题目,以及在实际开发中的应用来探讨这个问题。 本篇文章,主要介绍前缀树的概念以及两道经典的前缀树算法题。 文章目录1.前缀树概念2.实现Trie(Leetcode208)题目描述解题思路解答代码3.词典中最长的单词(Leetcode720)题目描述解题思路解答代码参考资料 1.前缀树概念 Trie(发音为"try")...

dsyblog 360

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

leetcode 720. 词典中最长的单词(前缀树,待研究)

【题目】720. 词典中最长的单词 给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。 若无答案,则返回空字符串。 示例 1: 输入: words = ["w","wo","wor","worl", "world"] 输出: "world" 解释: 单词"worl...

Sophia_fez的博客 511

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Leetcode每日一题 720. 词典中最长的单词 一题两做 从零到一掌握前缀树的基础理解我会啦~

📖本篇内容:Leetcode每日一题 720. 词典中最长的单词 一题三做 从零到一深刻掌握前缀树(感谢三叶姐姐和y总 )前缀树的基础理解我会啦~ 📑 文章专栏:leetcode每日一题《打卡日常》 📆 最近更新:2022 年 3 月 16日 Leetcode每日一题 432. 全 O(1) 的数据结构 双向链表+数据结构的巧妙合理设计 完成O(1)搜索 ⭐算法仓库:小付的算法之路——Alascanfu-algorithm.git.io 🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打.

Alascanfu的博客 631

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【LeetCode刷题(简单程度)】720. 词典中最长的单词

给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。 若无答案,则返回空字符串。 示例 1: 输入: words = [“w”,“wo”,“wor”,“worl”, “world”] 输出:“world” 解释: 单词"world"可由"w", “wo”, “wor”, 和 "worl"添加一个字母组成。 示例 2: 输入: words = [“a”, “banana”, “ap

qq_33197518的博客 520

720 词典中最长的单词(Trie树)

1. 问题描述: 给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。 示例 1: 输入: words = ["w","wo","wor","worl", "world"] 输出:"world" 解释: 单词"world"可由"w", "wo", "wor", 和 "worl"添加一个字母组成。 示例 2: 输入: words = ["a",.

二哈 360

LeetCode_前缀树_排序_哈希集合_中等_720.词典中最长的单词

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

代码星辰的博客 477

LeetCode——720. 词典中最长的单词

前缀树

weixin_44750790的博客 243

#力扣LeetCode720. 词典中最长的单词 @FDDLC

题目描述: 720. 词典中最长的单词 - 力扣(LeetCode) (leetcode-cn.com) 自测用例: ["w","wo","wor","worl","world"] ["a","banana","app","appl","ap","apply","apple"] ["ab","abc"] ["a"] ["a","b"] ["b","a"] ["a","b","bc"] ["ab"] ["rac","rs","ra","on","r","otif","o","onpdu","rsf

LiuXingchang的博客 454

力扣 720. 词典中最长的单词

题目 给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。 若无答案,则返回空字符串。 示例 输入: words = [“w”,“wo”,“wor”,“worl”, “world”] 输出:“world” 解释: 单词"world"可由"w", “wo”, “wor”, 和 "worl"添加一个字母组成。 输入: words = [“a”, “banana”, “app”, “a

(ง •_•)ง没有困难的工作,只有勇敢的狗狗 144

字典树 前缀树

字典树是一种数据结构,也叫前缀树、Trie树。比较常用的应用有前缀匹配和词频统计。

weixin_38384296的博客 382

【数据结构】前缀树/字典树

//插入一个新单词 public static void insert(TrieNode root,String str){ if(root==null||str.length()==0){ return; } char[] c=str.toCharArray(); for(int i=0; i<str.length(); i++){ //如果该分支不存在,创建一个新节点 if(root.nextNode[c[i]-'a']==null){ root....

littlemichelle 461

leetcode 720. 词典中最长的单词 java

排序:按长度升序,长度相同时按字典序降序 class Solution { public String longestWord(String[] words) { Arrays.sort(words,(a,b)-> { if(a.length()!=b.length()){ return a.length()-b.length(); } els

乾坤未定,你我皆是黑马 466

LeetCode题目分类整理

Hash相关 1、两数之和【简单】 387、字符串中第一个唯一字符【简单】

qq_40707462的博客 1430

前缀树(Trie)原理及Java实现

前缀树的结构Trie树,又叫字典树、前缀树(Prefix Tree)、单词查找树或键树,是一种多叉树结构。如下图: 上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。从上图可以归纳出Trie树的基本性质: ①根节点不包含字符,除根节点外的每一个子节点都包含一个字符。 ②从根节点到某一个节点,路径上经过的

有图有真相 2万+

leetcode:词典中最长的单词

题目来源:力扣 题目描述: 给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。 若无答案,则返回空字符串。 ================================================================ 示例 1: 输入: word...

zhangxiaojiakele的博客 894
上一篇: 算法竞赛入门经典第11章 最小生成树 Kruskal(克鲁斯卡尔)算法 和 Prim(普利姆)算法 详解及C++实现
下一篇: 转战Linux 重装系统记录 windows - fedora
哥布林军团
博客等级 码龄7年 5粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值