高级数据结构讲解与案例分析(二)

简介: 高级数据结构讲解与案例分析(二)

例题分析


LeetCode 第 785 题:给定一个无向图 graph,当这个图为二部图时返回 true。



提示:如果能将一个图的节点集合分割成两个独立的子集 A 和 B,并使图中的每一条边的两个节点一个来自 A 集合,一个来自 B 集合,就将这个图称为二部图。


解题思路


判断一个给定的任意图是否为二部图,就必须要对该图进行一次遍历:


  • 深度优先


  • 广度优先


(关于深度优先和广度优先算法,将在第 06 节课进行详细讨论)。



二部图,图的所有顶点可以分成两个子集 U 和 V,子集里的顶点互不直接相连,图里面所有的边,一头连着子集 U 里的顶点,一头连着子集 V 里的顶点。


image.png


给图里的顶点涂上颜色,子集 U 里的顶点都涂上红色,子集 V 里的顶点都涂上蓝色。


开始遍历这个图的所有顶点,想象一下手里握有红色和蓝色的画笔,每次交替地给遍历当中遇到的顶点涂上颜色。


如果这个顶点还没有颜色,那就给它涂上颜色,然后换成另外一支画笔。


下一个顶点,如果发现这个顶点已经涂上了颜色,而且颜色跟我手里画笔的颜色不同,那么表示这个顶点它既能在子集 U 里,也能在子集 V 里。


所以,它不是一个二部图。


前缀树(Trie)


应用场景


前缀树被广泛地运用在字典查找当中,也被称为字典树。


举例:给定一系列字符串,这些字符串构成了一种字典,要求你在这个字典当中找出所有以“ABC”开头的字符串。


解法 1:暴力搜索


直接遍历一遍字典,然后逐个判断每个字符串是否由“ABC”开头。假设字典很大,有 N 个单词,要对比的不是“ABC”,而是任意的,那不妨假设所要对比的开头平均长度为 M,那么时间复杂度是 O(M×N)。


解法 2:前缀树


如果用前缀树头帮助对字典的存储进行优化,那么可以把搜索的时间复杂度下降为 O(M),其中 M 表示字典里最长的那个单词的字符个数,在很多情况下,字典里的单词个数 N 是远远大于 M 的。因此,前缀树在这种场合中是非常高效的。


经典应用


网站上的搜索框会罗列出以搜索文字作为开头的相关搜索信息,这里运用了前缀树进行后端的快速检索。


汉字拼音输入法的联想输出功能也运用了前缀树。


举例:假如有一个字典,字典里面有如下词:"A","to","tea","ted","ten","i","in","inn",每个单词还能有自己的一些权重值,那么用前缀树来构建这个字典将会是如下的样子:


aHR0cDovL3d3dy5sZ3N0YXRpYy5jb20vaS9pbWFnZTIvTTAxLzkwL0QwL0Nnb3RPVjJJTFh5QUFidVBBQUh1TWpvUTBfTTMwNy5wbmc.png  


性质


1. 每个节点至少包含两个基本属性。


children:数组或者集合,罗列出每个分支当中包含的所有字符


isEnd:布尔值,表示该节点是否为某字符串的结尾


2. 前缀树的根节点是空的


所谓空,即只利用到这个节点的 children 属性,即只关心在这个字典里,有哪些打头的字符。


3. 除了根节点,其他所有节点都有可能是单词的结尾,叶子节点一定都是单词的结尾。


实现


前缀树最基本的操作就是两个:创建和搜索。


1. 创建


  • 遍历一遍输入的字符串,对每个字符串的字符进行遍历


  • 从前缀树的根节点开始,将每个字符加入到节点的 children 字符集当中。


  • 如果字符集已经包含了这个字符,则跳过。


  • 如果当前字符是字符串的最后一个,则把当前节点的 isEnd 标记为真。


由上,创建的方法很直观。


前缀树真正强大的地方在于,每个节点还能用来保存额外的信息,比如可以用来记录拥有相同前缀的所有字符串。因此,当用户输入某个前缀时,就能在 O(1) 的时间内给出对应的推荐字符串。


2. 搜索


与创建方法类似,从前缀树的根节点出发,逐个匹配输入的前缀字符,如果遇到了就继续往下一层搜索,如果没遇到,就立即返回。


目录
相关文章
|
5月前
|
存储 算法 数据安全/隐私保护
【Python学习篇】Python实验小练习——高级数据结构(五)
【Python学习篇】Python实验小练习——高级数据结构(五)
66 1
|
4月前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
44 1
|
4月前
|
存储 算法 调度
惊呆了!Python高级数据结构堆与优先队列,竟然能这样优化你的程序性能!
【7月更文挑战第10天】Python的heapq模块实现了堆和优先队列,提供heappush和heappop等函数,支持O(log n)时间复杂度的操作。优先队列常用于任务调度和图算法,优化性能。例如,Dijkstra算法利用最小堆加速路径查找。堆通过列表存储,内存效率高。示例展示了添加、弹出和自定义优先级元素。使用堆优化程序,提升效率。
62 2
|
5月前
|
存储 测试技术
【数据结构】手把手分析:链式二叉树的实现
【数据结构】手把手分析:链式二叉树的实现
37 5
|
4月前
|
存储 数据处理 开发者
告别繁琐查找!Python高级数据结构Trie树与Suffix Tree,让数据处理更轻松!
【7月更文挑战第19天】Python的Trie树优化字符串搜索,利用前缀减少无效操作,提升效率;Suffix Tree则高效处理后缀问题,尤其适用于文本搜索与生物信息学。虽构建复杂,但能加速后缀查询。掌握这两种数据结构,能有效应对大规模数据挑战,简化处理流程,提升开发效率。
112 0
|
4月前
|
算法 安全 调度
逆天改命!Python高级数据结构堆(Heap)与优先队列,让你的算法效率飙升至宇宙级!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue实现了堆和优先队列,提供高效算法解决方案。堆用于Dijkstra算法求解最短路径,例如在图论问题中;PriorityQueue则在多线程下载管理中确保高优先级任务优先执行。这两个数据结构提升效率,简化代码,是编程中的强大工具。
50 0
|
4月前
|
存储 算法 安全
解锁Python高级数据结构新姿势:堆与优先队列的实战演练,让你的代码更优雅!
【7月更文挑战第8天】Python的`heapq`模块和`queue.PriorityQueue`提供堆与优先队列功能,用于高效数据管理。堆是完全二叉树,`heapq`实现最小堆,常用于任务调度,如按优先级执行任务。当需要线程安全且更复杂操作时,`queue.PriorityQueue`成为优选,例如在管理网络请求时按优先级处理。这两个数据结构能提升代码效率和可读性。
39 0
|
6月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
53 1
|
5月前
|
算法
数据结构和算法——散列函数的构造方法(直接定址法、除留余数法、数字分析法、折叠法、平方取中法、ASCII码加和法、前三字符移位法)
数据结构和算法——散列函数的构造方法(直接定址法、除留余数法、数字分析法、折叠法、平方取中法、ASCII码加和法、前三字符移位法)
63 0
|
5月前
|
算法 搜索推荐
数据结构和算法——表排序(算法概述、物理排序、复杂度分析,包含详细清晰图示过程)
数据结构和算法——表排序(算法概述、物理排序、复杂度分析,包含详细清晰图示过程)
43 0

热门文章

最新文章

下一篇
无影云桌面