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

【Leetcode hot 100】208.实现Trie(前缀树)

问题链接

208.实现Trie(前缀树)

问题描述

Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。

请你实现 Trie 类:

  • Trie() 初始化前缀树对象。
  • void insert(String word) 向前缀树中插入字符串 word
  • boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false
  • boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false

示例:

输入
[“Trie”, “insert”, “search”, “search”, “startsWith”, “insert”, “search”]
[[], [“apple”], [“apple”], [“app”], [“app”], [“app”], [“app”]]
输出
[null, null, true, false, true, null, true]

解释

Trie trie = new Trie();
trie.insert(“apple”);
trie.search(“apple”); // 返回 True
trie.search(“app”); // 返回 False
trie.startsWith(“app”); // 返回 True
trie.insert(“app”);
trie.search(“app”); // 返回 True

提示:

  • 1 <= word.length, prefix.length <= 2000
  • wordprefix 仅由小写英文字母组成
  • insertsearchstartsWith 调用次数 总计 不超过 3 * 10^4

问题解答

1. 前缀树(Trie)核心原理

前缀树是一种专门用于高效存储和检索字符串的树形数据结构,其核心特点是:

  • 节点不存储完整字符:每个节点代表字符串的一个字符片段,通过节点在树中的路径拼接出完整字符串。
  • 子节点数组优化:因题目限定仅含小写英文字母,每个节点用大小为 26 的数组存储子节点(对应 a-z),索引通过 字符 - 'a' 计算。
  • 单词结尾标记:每个节点用布尔值 isEndOfWord 标记是否为某个单词的结尾,避免混淆“前缀”和“完整单词”(如区分 appapple)。

2. 完整Java代码实现

class Trie {// 前缀树节点类(静态内部类,仅服务于Trie)private static class TrieNode {// 存储子节点:索引 0-25 对应 a-zTrieNode[] children;// 标记当前节点是否为某个单词的结尾boolean isEndOfWord;// 节点构造器:初始化子节点数组(默认全为null),标记为非单词结尾public TrieNode() {children = new TrieNode[26]; // 仅小写英文字母,大小固定26isEndOfWord = false;}}// 前缀树的根节点(空节点,不对应任何字符)private TrieNode root;// 初始化前缀树(根节点为空)public Trie() {root = new TrieNode();}/*** 向前缀树插入单词* @param word 待插入的字符串(仅小写英文字母)*/public void insert(String word) {// 从根节点开始遍历TrieNode currentNode = root;for (int i = 0; i < word.length(); i++) {char c = word.charAt(i);// 计算当前字符对应的子节点索引(a->0, b->1, ..., z->25)int index = c - 'a';// 若当前字符的子节点不存在,创建新节点if (currentNode.children[index] == null) {currentNode.children[index] = new TrieNode();}// 移动到子节点,继续处理下一个字符currentNode = currentNode.children[index];}// 遍历完所有字符后,标记当前节点为单词结尾currentNode.isEndOfWord = true;}/*** 搜索单词是否在前缀树中(需是完整单词)* @param word 待搜索的字符串* @return 存在则返回true,否则返回false*/public boolean search(String word) {// 从根节点开始遍历,找到单词最后一个字符对应的节点TrieNode currentNode = root;for (int i = 0; i < word.length(); i++) {char c = word.charAt(i);int index = c - 'a';// 若中途某个字符的子节点不存在,说明单词不存在if (currentNode.children[index] == null) {return false;}currentNode = currentNode.children[index];}// 遍历完所有字符后,需确认当前节点是单词结尾(避免仅为前缀的情况)return currentNode.isEndOfWord;}/*** 判断前缀树中是否存在以指定前缀开头的单词* @param prefix 待判断的前缀* @return 存在则返回true,否则返回false*/public boolean startsWith(String prefix) {// 逻辑与search类似,但无需判断是否为单词结尾TrieNode currentNode = root;for (int i = 0; i < prefix.length(); i++) {char c = prefix.charAt(i);int index = c - 'a';if (currentNode.children[index] == null) {return false;}currentNode = currentNode.children[index];}// 遍历完所有前缀字符,说明前缀存在return true;}// 测试示例(与题目示例一致)public static void main(String[] args) {Trie trie = new Trie();trie.insert("apple");System.out.println(trie.search("apple"));   // 输出:trueSystem.out.println(trie.search("app"));     // 输出:falseSystem.out.println(trie.startsWith("app")); // 输出:truetrie.insert("app");System.out.println(trie.search("app"));     // 输出:true}
}

3. 关键方法解析

TrieNode 节点类

  • children 数组:大小固定为 26,对应 a-z 26个小写英文字母,避免哈希表的额外开销,访问效率为 O(1)
  • isEndOfWord 标记:例如插入 apple 后,e 对应的节点 isEndOfWord = true,而 p(第三个字符)对应的节点为 false,因此 search("app") 会返回 false

insert 插入方法

  1. 根节点开始,逐个处理单词的每个字符。
  2. 对每个字符,计算其在 children 数组中的索引(c - 'a')。
  3. 若对应索引的子节点为空,创建新节点;否则直接复用已有节点。
  4. 处理完所有字符后,将最后一个节点的 isEndOfWord 设为 true,标记单词结束。

search 搜索方法

  1. 流程与 insert 一致,逐个匹配字符。
  2. 若中途某字符的子节点不存在,直接返回 false(单词不存在)。
  3. 匹配完所有字符后,必须检查当前节点的 isEndOfWord:仅当为 true 时,才说明是完整单词(而非前缀)。

startsWith 前缀判断方法

  1. 流程与 search 一致,逐个匹配前缀字符。
  2. 若中途某字符的子节点不存在,返回 false
  3. 匹配完所有前缀字符后,直接返回 true(无需判断 isEndOfWord,因为只需确认前缀存在)。

4. 复杂度分析

方法时间复杂度空间复杂度
insertO(L)O(L)
searchO(L)O(1)
startsWithO(L)O(1)
  • L:输入字符串(单词或前缀)的长度。
  • 时间复杂度:每个方法均需遍历字符串的所有字符,故为 O(L),与插入的单词总数无关。
  • 空间复杂度insert 需创建新节点,空间开销与字符串长度 L 成正比;searchstartsWith 仅遍历节点,无额外空间开销。

5. 应用场景

前缀树的高效性使其在以下场景中广泛应用:

  • 搜索引擎自动补全(如输入“app”提示“apple”“application”)。
  • 拼写检查器(快速判断单词是否存在)。
  • 词频统计(在节点中增加 count 字段统计单词出现次数)。
  • IP 路由最长前缀匹配(网络领域的经典应用)。
http://www.dtcms.com/a/420018.html

相关文章:

  • 【开题答辩全过程】以 基于Java的网上租车系统的设计与开发为例,包含答辩的问题和答案
  • Linux系统编程深度指南:与内核的对话
  • 资源库建设网站工信部网站 登陆
  • 贵州住房和城乡建设部网站官网网站建设怎样
  • C++IO流学习
  • 网站建设哪里可以学招聘网官网
  • 队列+宽搜(BFS)-515.在每个树行中找最大值-力扣(LeetCode)
  • 网站建设升级的必要性做网站用什么服务器会比较好
  • 摄影网站开发的背景网站设计专题页
  • 网站备案 查询wordpress媒体优化
  • 商业网站的域名后缀是什么wordpress+信息流
  • 邢台网站制作哪里做做网站需要vps吗
  • 解锁数据湖潜力:Databricks Photon引擎的技术深度剖析
  • 网站建设优化排名网页qq登录不扫二维码
  • 《Nat. Commun》重磅:MXene赋能石墨负极,-20°C低温下循环1200次容量保持93%
  • 【开题答辩全过程】以 基于Java的网上图书管理系统为例,包含答辩的问题和答案
  • think-queue for ThinkPHP6 使用方法教程
  • 自学编程网站免费湖北网络推广有限公司
  • Playwright web爬虫与AI智能体
  • 成品网站1688入门网用手机开发app的软件
  • 做网站ddos攻击社交网络推广方法
  • 完全免费,比DC好用了
  • 网站优化排名易下拉排名wordpress转移typecho
  • 力扣hot100 617. 合并二叉树
  • 海淀营销型网站建设社交网站开发平台
  • 建设工程 法律 网站英语网站大全免费
  • 怎么管理网站添加代码扬州专业外贸网站建设推广
  • 网站空间商怎么做游戏推广工作好做吗
  • 怎样弄一个网站wordpress 用不了矢量
  • DC24V-36V/4.5A H桥直流有刷电机驱动芯片AH6240