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

Python算法题集_实现 Trie [前缀树]

 Python算法题集_实现 Trie [前缀树]

  • 题208:实现 Trie (前缀树)
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【定义数据类+默认字典】
    • 2) 改进版一【初始化字典+无额外类】
    • 3) 改进版二【字典保存结尾信息+无额外类】
  • 4. 最优算法
  • 5. 相关资源

本文为Python算法题集之一的代码示例

题208:实现 Trie (前缀树)

1. 示例说明

  • 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 * 104

2. 题目解析

- 题意分解

  1. 本题是为自动补完、拼写检查等创造一个高效率的检索类
  2. 基本的设计思路迭代单词,每层用字典保存,同时还需要保存单词结尾信息【search检测结尾、startWith不检测】

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 可以尝试使用默认字典defaultdict

    2. 本题都是小写字母,因此26个元素的字典就可以保存一个层级

    3. 所有单词字符都是ASCII码,Ord值都在0-127,因此128个元素的字典可以正常使用【超时测试用例,需要128一层】

    4. 可以考虑将单词结尾信息保存在字典中,用一个单词中不会出现的字符即可,比如’#’


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见章节【最优算法】,需要安装和部署**NLTK**

3. 代码展开

1) 标准求解【定义数据类+默认字典】

使用默认字典,定位专门的数据类,使用类属性保存单词结尾信息

页面功能测试,马马虎虎,超过33%在这里插入图片描述

import CheckFuncPerf as cfpclass prenode:def __init__(self):self.chars = defaultdict(int)class Trie_base:def __init__(self):self.node = prenode()self.bEnd = Falsedef searchPrefix(self, prefix):tmpNode = selffor achar in prefix:ichar = ord(achar) - ord("a")if tmpNode.node.chars[ichar] == 0:return NonetmpNode = tmpNode.node.chars[ichar]return tmpNodedef insert(self, word):tmpNode = selffor achar in word:ichar = ord(achar) - ord("a")if tmpNode.node.chars[ichar] == 0:tmpNode.node.chars[ichar] = Trie_base()tmpNode = tmpNode.node.chars[ichar]tmpNode.bEnd = Truedef search(self, word):node = self.searchPrefix(word)return node is not None and node.bEnddef startsWith(self, prefix):return self.searchPrefix(prefix) is not NonetmpTrie = Trie_base()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testTrie 的运行时间为 7127.62 ms;内存使用量为 373008.00 KB 执行结果 = 99

2) 改进版一【初始化字典+无额外类】

将字典数据和单词结尾信息都保存在节点类中,创建类同时初始化字典的128个元素【按题意只需26,本类已经按超时测试改写】

页面功能测试,马马虎虎,超过65%在这里插入图片描述

import CheckFuncPerf as cfpclass Trie_ext1:def __init__(self):self.data = [None] * 128self.bEnd = Falsedef searchPrefix(self, prefix):tmpnode = selffor achar in prefix:ichar = ord(achar)if not tmpnode.data[ichar]:return Nonetmpnode = tmpnode.data[ichar]return tmpnodedef insert(self, word):tmpnode = selffor achar in word:ichar = ord(achar)if not tmpnode.data[ichar]:tmpnode.data[ichar] = Trie_ext1()tmpnode = tmpnode.data[ichar]tmpnode.bEnd = Truedef search(self, word):tmpnode = self.searchPrefix(word)return tmpnode is not None and tmpnode.bEnddef startsWith(self, prefix):return self.searchPrefix(prefix) is not NonetmpTrie = Trie_ext1()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testTrie 的运行时间为 5857.32 ms;内存使用量为 793700.00 KB 执行结果 = 99

3) 改进版二【字典保存结尾信息+无额外类】

在字典中保存单词结尾信息,将字典数据保存在节点类中,创建类时不初始化字典

页面功能测试,性能卓越,超越96%在这里插入图片描述

import CheckFuncPerf as cfpclass Trie_ext2:def __init__(self):self.tree = {}def insert(self, word):tree = self.treefor achar in word:if achar not in tree:tree[achar] = {}tree = tree[achar]tree["#"] = "#"def search(self, word):tree = self.treefor achar in word:if achar not in tree:return Falsetree = tree[achar]return "#" in treedef startsWith(self, prefix):tree = self.treefor achar in prefix:if achar not in tree:return Falsetree = tree[achar]return TruetmpTrie = Trie_ext2()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testTrie 的运行时间为 1670.38 ms;内存使用量为 146692.00 KB 执行结果 = 99

4. 最优算法

根据本地日志分析,最优算法为第3种方式【字典保存结尾信息+无额外类】Trie_ext2

本题大概有以下结论:

  1. 独立的变量,如果能保存在字典结构里,减少独立的变量数,可以提升性能
  2. 数据集的默认初始化可能会扩大内存使用,同时数据量过大、内存过大也拖累性能
import random
from nltk.corpus import words
word_list = list(words.words())
def testTrie(aTrie, actions):for act in actions:if act[0]==1:   # insertaTrie.insert(act[1])elif act[0]==2: # searchaTrie.search(act[1])elif act[0]==3: # startsWithaTrie.startsWith(act[1])return 99
import random
actions = []
iLen = 1000000
for iIdx in range(iLen):actions.append([random.randint(1, 3), random.choice(word_list)])
tmpTrie = Trie_base()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))
tmpTrie = Trie_ext1()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))
tmpTrie = Trie_ext2()
result = cfp.getTimeMemoryStr(testTrie, tmpTrie, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 算法本地速度实测比较
函数 testTrie 的运行时间为 7127.62 ms;内存使用量为 373008.00 KB 执行结果 = 99
函数 testTrie 的运行时间为 5857.32 ms;内存使用量为 793700.00 KB 执行结果 = 99
函数 testTrie 的运行时间为 1670.38 ms;内存使用量为 146692.00 KB 执行结果 = 99

5. 相关资源

本文代码已上传到CSDN,地址:**Python算法题源代码_LeetCode(力扣)_**实现Trie(前缀树)

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

相关文章:

Python算法题集_实现 Trie [前缀树]

Python算法题集_实现 Trie [前缀树] 题208&#xff1a;实现 Trie (前缀树)1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【定义数据类默认字典】2) 改进版一【初始化字典无额外类】3) 改进版二【字典保存结尾信息无额外类】 4. 最优算法5. 相关…...

pytorch简单新型模型测试参数

import torch from torch.nn import Conv2d,MaxPool2d,Sequential,Flatten,Linear import torchvision import torch.optim.optimizer from torch.utils.data import DataLoader,dataset from torch import nn import torch.optim.optimizer# 建模 model nn.Linear(2,1)#损失 …...

Unity中URP下实现水体(水面高光)

文章目录 前言一、实现高光反射原理1、原理&#xff1a;2、公式&#xff1a; 二、实现1、定义 _SpecularColor 作为高光反射的颜色2、定义 _SpecularIntensity 作为反射系数&#xff0c;控制高光反射的强度3、定义 _Smoothness 作为高光指数&#xff0c;用于模型高光范围4、模拟…...

26.HarmonyOS App(JAVA)列表对话框

列表对话框的单选模式&#xff1a; //单选模式 // listDialog.setSingleSelectItems(new String[]{"第1个选项","第2个选项"},1);//单选 // listDialog.setOnSingleSelectListener(new IDialog.ClickedListener() { // Override …...

五种主流数据库:常用字符函数

SQL 字符函数用于字符数据的处理&#xff0c;例如字符串的拼接、大小写转换、子串的查找和替换等。 本文比较五种主流数据库常用数值函数的实现和差异&#xff0c;包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite。 字符函数函数功能MySQLOracleSQL ServerPostgreSQ…...

软考笔记--企业资源规划和实施

企业资源是指企业业务活动和战略运营的事物&#xff0c;包括人、财和物&#xff0c;也包括信息资源&#xff0c;同时也包括企业的内部和外部资源。企业资源可以归纳为物流&#xff0c;资金流和信息流。企业资源规划&#xff08;ERP&#xff09;是只建立在信息技术基础上&#x…...

React歌词滚动效果(跟随音乐播放时间滚动)

首先给audio绑定更新时间事件 const updateTime e > {console.log(e.target.currentTime)setCurrentTime(e.target.currentTime);};<audiosrc{currentSong.url}ref{audio}onCanPlay{ready}onEnded{end}onTimeUpdate{updateTime}></audio>当歌曲播放时间改变的时…...

java面试题之mybatis篇

什么是ORM&#xff1f; ORM&#xff08;Object/Relational Mapping&#xff09;即对象关系映射&#xff0c;是一种数据持久化技术。它在对象模型和关系型数据库直接建立起对应关系&#xff0c;并且提供一种机制&#xff0c;通过JavaBean对象去操作数据库表的数据。 MyBatis通过…...

Java的编程之旅19——使用idea对面相对象编程项目的创建

在介绍面向对象编程之前先说一下我们在idea中如何创建项目文件 使用快捷键CtrlshiftaltS新建一个模块&#xff0c;点击“”&#xff0c;再点New Module 点击Next 我这里给Module起名叫OOP,就是面向对象编程的英文缩写&#xff0c;再点击下面的Finish 点Apply或OK均可 右键src…...

docker build基本命令

背景 我们经常会构建属于我们应用自己的镜像&#xff0c;这种情况下编写dockerfile文件不可避免&#xff0c;本文就来看一下常用的dockerfile的指令 常用的dockerfile的指令 首先我们看一下docker build的执行过程 ENV指令&#xff1a; env指令用于设置shell的环境变量&am…...

nginx高级配置详解

目录 一、网页的状态页 1、状态页的基本配置 2、搭配验证模块使用 3、结合白名单使用 二、nginx 第三方模块 1、echo模块 1.1 编译安装echo模块 1.2 配置echo模块 三、nginx变量 1、内置变量 2、自定义变量 四、自定义图标 五、自定义访问日志 1、自定义日志格式…...

小程序--分包加载

分包加载是优化小程序加载速度的一种手段。 一、为什么进行分包 小程序限制单个包体积不超过2M&#xff1b; 分包可以优化小程序页面的加载速度。 二、启用/使用分包语法subPackages subPackages&#xff1a;下载app.json文件中 root&#xff1a;分包所在的目录 pages&#x…...

R语言【base】——writeLines()

Package base version 4.2.0 Description 向连接写入文本行。 Usage writeLines(text, con stdout(), sep "\n", useBytes FALSE) Arguments 参数【text】&#xff1a;一个字符向量。 参数【con】&#xff1a;一个 connection 对象 或 一个字符串。 参数【se…...

微信小程序-人脸检测

微信小程序的人脸检测功能&#xff0c;配合蓝牙&#xff0c;配合ESP32 可以实现一些有趣的玩具 本文先只说微信小程序的人脸检测功能 1、人脸检测使用了摄像头&#xff0c;就必须在用户隐私权限里面声明。 修改用户隐私声明后&#xff0c;还需要等待审核&#xff0c;大概一天 …...

微信小程序自制动态导航栏

写在前面 关于微信小程序导航栏的问题以及解决办法我已经在先前的文章中有提到&#xff0c;点击下面的链接即可跳转~ &#x1f90f;微信小程序自定义的导航栏&#x1f90f; 在这篇文章中我们需要做一个这样的导航栏&#xff01;先上效果图 &#x1f447;&#x1f447;&#x1f…...

金融知识分享系列之:五日线

金融知识分享系列之&#xff1a;五日线 一、股票均线二、五日线三、五日线加量能三、五日线案例四、五日线案例五、五日线案例六、五日线案例七、五日线案例八、五日线案例 一、股票均线 股票均线是一种用于平滑股票价格的指标。它是根据一段时间内的股票价格计算得出的平均值…...

回归测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 什么是回归测试 回归测试&#xff08;Regression testi…...

渲染效果图有哪几种分类?效果图为什么用云渲染更快

云渲染利用了集群化的云端服务器资源&#xff0c;通过并行计算充分发挥了高性能硬件的优势&#xff0c;显著提升了渲染的速度。这一技术特别适用于处理规模庞大或细节丰富的渲染任务&#xff0c;在缩短项目完成时间方面表现卓越。无论是用于为建筑提供精确的可视化效果图&#…...

Docker镜像加速

前言 众所周知&#xff0c;我们常用的一些工具或系统的下载源都是国外的&#xff0c;这就会导致我们在下载一些东西时&#xff0c;会导致下载巨慢或者下载失败的情况&#xff0c;下面便是docker换下载源的教程 镜像加速 下面是几个常用的国内的镜像 科大镜像&#xff1a;ht…...

吴恩达deeplearning.ai:sigmoid函数的替代方案以及激活函数的选择

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 文章目录 引入——改进下需求预测模型ReLU函数(整流线性单元 rectified linear unit&#xff09;线性激活函数(linear activation function)激活函数的选择实现方式为什么需要激活函数 到现在…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...