前缀树(字典树/Trie) -----Java实现

目录

一.前缀树

1.什么是前缀树

2.前缀树的举例

二.前缀树的实现 

1.前缀树的数据结构

1.插入字符串

2.查找字符串

3.查找前缀

三.词典中最长的单词

1.题目描述

2.问题分析

3.代码实现


一.前缀树

1.什么是前缀树

字典树(Trie树)是一种树形数据结构,常用于字符串的存储和查找。字典树的核心思想是利用字符串之间的公共前缀来节省存储空间和提高查询效率。它是一棵多叉树,每个节点代表一个字符串的前缀,从根节点到叶子节点的路径组成一个字符串

字典树的根节点不包含字符,每个子节点代表一个字符,从根节点到任意一个节点所经过的路径上的字符连接起来即为该节点所代表的字符串。每个节点可以存储一个或多个字符串,通常使用一个标志来标记一个节点代表的字符串是否存在。当需要在一组字符串中查找某个字符串时,可以利用字典树来实现高效的查找操作。

2.前缀树的举例

例如对字符串数组{"goog","google","bai","baidu","a"}建立前缀树,此时我们可以很清晰的看到前缀树的一些特征:

  • 根结点不保存字符
  • 前缀树是一颗多叉树
  • 前缀树的每个节点保存一个字符
  • 具有相同前缀的字符串保存在同一条路径上
  • 字符串的尾处相应的在前缀树上也有结束的标志

二.前缀树的实现 

 力扣上的208题就是实现前缀树:力扣

1.前缀树的数据结构

在写代码的时候,我偏向于用哈希表来存储结点的信息,有的也可以用数组来存储结点的信息,本质上都是一样的

public class Trie {
    Map<Character, Trie> next;
    boolean isEnd;

    public Trie() {
        this.next = new HashMap<>();
        this.isEnd = false;
    }


    public void insert(String word) {

    }

    public boolean search(String word) {
        return false;

    }

    public boolean startsWith(String prefix) {
        return false;

    }
}

1.插入字符串

    public void insert(String word) {
        Trie trie = this;//获得根结点
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//当前结点不存在
                trie.next.put(c, new Trie());//创建当前结点
            }
            trie = trie.next.get(c);//得到字符c的结点,继续向下遍历
        }
        trie.isEnd = true;

    }

2.查找字符串

    public boolean search(String word) {
        Trie trie = this;//获得根结点
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//当前结点不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的结点,继续向下遍历
        }
        return trie.isEnd;

    }

3.查找前缀

    public boolean startsWith(String prefix) {
        Trie trie = this;//获得根结点
        for (char c : prefix.toCharArray()) {
            if (trie.next.get(c) == null) {//当前结点不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的结点,继续向下遍历
        }
        return true;

    }

接下来是力扣上关于前缀树的一些题目

三.词典中最长的单词

1.题目描述

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

力扣:力扣

2.问题分析

这是一道典型的前缀树的问题,但是这一题有一些特殊的要求,返回的答案是:

1.最长的单词 2.这个单词由其他单词逐步构成  3.长度相同返回字典序小的

因此我们需要对前缀树的相关代码进行修改,把字符串一一插入的代码还是不改变的,主要修改的是查找的代码,应该在 trie.next.get(c) == null在增加一个判断为false的条件,就是每一个结点都应该有一个标志true,表示每个节点都存在一个单词,最终一步步构成最长的单词(叶子结点的单词)

3.代码实现

class Solution {
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }
        String longest = "";
        for (String word : words) {
            if (trie.search(word)) {
                if (word.length() > longest.length() || ((word.length() == longest.length()) && (word.compareTo(longest) < 0))) {
                    longest = word;
                }

            }
        }
        return longest;
    }
}
class Trie {
    Map<Character, Trie> next;
    boolean isEnd;

    public Trie() {
        this.next = new HashMap<>();
        this.isEnd = false;
    }


    public void insert(String word) {
        Trie trie = this;//获得根结点
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//当前结点不存在
                trie.next.put(c, new Trie());//创建当前结点
            }
            trie = trie.next.get(c);//得到字符c的结点,继续向下遍历
        }
        trie.isEnd = true;

    }

    public boolean search(String word) {
        Trie trie = this;//获得根结点
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null || !trie.next.get(c).isEnd) {//当前结点不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的结点,继续向下遍历
        }
        return trie.isEnd;

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/2113.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习——无监督学习

机器学习的分类一般分为下面几种类别&#xff1a;监督学习( supervised Learning )无监督学习( Unsupervised Learning )强化学习( Reinforcement Learning&#xff0c;增强学习)半监督学习( Semi-supervised Learning )深度学习(Deep Learning)Python Scikit-learn. http: // …

用Pytorch构建一个喵咪识别模型

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 目录 一、前言 二、问题阐述及理论流程 2.1问题阐述 2.2猫咪图片识别原理 三、用PyTorch 实现 3.1PyTorch介绍 3.2PyTorch 构建模型的五要素 3.3PyTorch 实现的步骤 3.3.…

app自动化测试——app自动化控制、常见控件定位方法

文章目录一、app自动化控制1、清理数据&#xff1a;2、启动&#xff1a;3、关闭&#xff1a;二、常见控件定位方法1、android知识2、ios 基础知识3、元素定位4、控件基础知识5、app dom 结构解析6、iOS 与 Android dom 结构的区别7、定位方法测试步骤三要素定位方式&#xff1a…

大环境不好,找工作太难?三面阿里,幸好做足了准备,已拿offer

三面大概九十分钟&#xff0c;问的东西很全面&#xff0c;需要做充足准备&#xff0c;就是除了概念以外问的有点懵逼了&#xff08;呜呜呜&#xff09;。回来之后把这些题目做了一个分类并整理出答案&#xff08;强迫症的我狂补知识&#xff09;分为软件测试基础、Python自动化…

超专业解析!10分钟带你搞懂Linux中直接I/O原理

我们先看一张图&#xff1a; 这张图大体上描述了 Linux 系统上&#xff0c;应用程序对磁盘上的文件进行读写时&#xff0c;从上到下经历了哪些事情。 这篇文章就以这张图为基础&#xff0c;介绍 Linux 在 I/O 上做了哪些事情。 文件系统 什么是文件系统 文件系统&#xff0…

docker版jxTMS使用指南:数据查询

本文讲解docker版jxTMS的数据查询&#xff0c;整个系列的文章请查看&#xff1a;docker版jxTMS使用指南 请按前文所述先做好相关的准备工作&#xff0c;然后多在helloWorld界面输入各种数据后点【点我】按钮&#xff0c;以多创建点数据来为查询做下准备。 分页查询 首先在we…

python网上选课系统django-PyCharm

学生选课信息管理系统&#xff0c;可以有效的对学生选课信息、学生个人信息、教师个人信息等等进行管理。 开发语言&#xff1a;Python 框架&#xff1a;django Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#x…

RK3588平台开发系列讲解(NPU篇)NPU调试方法

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、日志等级二、NPU 支持查询设置项沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们一起来看一下NPU的调试方法。 一、日志等级 NPU 的运行库会根据开发板上的系统环境变量输出一些日志信息或者生成…

操作系统(2.4.5)--管程机制

1.管程的定义 利用共享数据结构抽象地表示系统中的共享资源&#xff0c;而把对该共享数据结构实施的操作定义为一组过程进程对共享资源的申请、释放和其它操作&#xff0c;都是通过这组过程对共享数据结构的操作来实现的&#xff0c;这组过程还可以根据资源的情况&#xff0c;或…

yolov8训练筷子点数数据集

序言 yolov8发布这么久了&#xff0c;一直没有机会尝试一下&#xff0c;今天用之前自己制作的筷子点数数据集进行训练&#xff0c;并且记录一下使用过程以及一些常见的操作方式&#xff0c;供以后翻阅。 一、环境准备 yolov8的训练相对于之前的yolov5简单了很多&#xff0c;…

【链表OJ题(九)】环形链表延伸问题以及相关OJ题

环形链表OJ题 1. 环形链表 链接&#xff1a;141. 环形链表 描述&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&…

简单分析Linux内核基础篇——initcall

写过Linux驱动的人都知道module_init宏&#xff0c;因为它声明了一个驱动的入口函数。 除了module_init宏&#xff0c;你会发现在Linux内核中有许多的驱动并没有使用module_init宏来声明入口函数&#xff0c;而是看到了许多诸如以下的声明&#xff1a; static int __init qco…

Java之类与对象(图文结合)

目录 一、面向对象的初步认知 1、什么是面向对象 2、面向对象与面向过程 二、类定义和使用 1、简单认识类 2、类的定义格式 3、练习 &#xff08;1&#xff09;定义一个狗类 &#xff08;2&#xff09;定义一个学生类 三、类的实例化 1、什么是实例化 2、类和对象的…

CSDN 周赛38期题解

CSDN 周赛38期题解1、题目名称&#xff1a;代写匿名信2、题目名称&#xff1a;寻因找祖3、题目名称&#xff1a;小Q新式棋盘4、题目名称&#xff1a;拯救公主结束语1、题目名称&#xff1a;代写匿名信 小Q想要匿名举报XX领导不务正业&#xff01; 小Q害怕别人认出他的字迹。 他…

【数据结构】Java实现双向链表

目录 1. 接口的实现 2. 动手实现双链表 2.1 重写SeqList接口方法 2.2 在当前链表尾部添加节点&#xff08;尾插&#xff09; 2.3 在当前链表头部添加节点&#xff08;头插&#xff09; 2.4 检验index是否合法 2.5 在 第index位置添加节点&#xff08;任意位置&#xff09; 2.6 …

【精品】华为认证数通HCIA+HCIP题库分享(含答案解析)

嗨~大家好久不见&#xff0c;我是薄荷学姐&#xff0c;随着华为业务也全球领域的迅猛发展&#xff0c;越来越多人开始重视华为认证的重要性。今天给大家分享一下去年8月份的题库&#xff0c;基本都是一样&#xff0c;希望可以帮助到大家哈想要通过华为认证&#xff0c;除了进行…

gdb调试工具和makemakefile工具

gdb调试工具和make/makefile工具 文章目录gdb调试工具和make/makefile工具一、gdb调试工具1.debug/release2.使用二、make/makefile1.什么是make/makefile2.编写一、gdb调试工具 1.debug/release 程序有两种默认的发布方式debug和release。release是无法进行调试的。Linux中g…

Bing+ChatGPT 对传统搜索引擎的降维打击

早些时候申请了新版 Bing 的内测资格&#xff0c;终于收到了通过的邮件。 一天的体验之后&#xff0c;我的感受是&#xff1a;当新版 Bing 具备了 ChatGPT 的聊天能力之后&#xff0c;它的能力不论是对传统搜索引擎&#xff0c;还是 ChatGPT 自身&#xff0c;都将是降维打击。 …

菜鸟刷题Day3

⭐作者&#xff1a;别动我的饭 ⭐专栏&#xff1a;菜鸟刷题 ⭐标语&#xff1a;悟已往之不谏&#xff0c;知来者之可追 一.字符串压缩&#xff1a;面试题 01.06. 字符串压缩 - 力扣&#xff08;LeetCode&#xff09; 描述 字符串压缩。利用字符重复出现的次数&#xff0c;编…

Python程序员看见一个好看的手机壁纸网站,开撸!

人生苦短&#xff0c;我用python 最近好像没什么大事&#xff0c; .那就采集一下小——姐——姐————看下吧~ python 安装包资料:点击此处跳转文末名片获取 最近有同学的爬虫代码出了bug&#xff0c;给问我怎么改 于是就发现了这个好看的手机壁纸网站。 这个图片应该是违规…