
数据结构和算法
文章平均质量分 86
主要介绍基础的数据结构
xiaoyu❅
云水随缘道自安,良知一念照心山。无为法外乾坤阔,致知行中天地宽。风起青萍知运化,月临沧海见澄澜。逍遥何必寻蓬岛?万物同春共此寰。
展开
-
区间信息操作之树状数组(Fenwick Tree)原理
树状数组是一种基于二进制索引单点更新(Update):在O(log n)时间内更新某个元素的值。前缀和查询(Query):在O(log n)时间内查询前i个元素的和。区间和查询(Range Query):通过两次前缀和查询得到区间[L, R]的和。树状数组是处理动态区间和问题的利器,尤其适合需要频繁更新和查询的场景(如实时数据统计)。对于更复杂的区间操作(如区间修改、区间最值),可考虑线段树(Segment Tree)结构。原创 2025-03-25 11:19:53 · 372 阅读 · 0 评论 -
字符串处理之后缀数组(Suffix Array)原理
后缀数组(Suffix Array)是某个字符串的所有后缀按字典序排序后的数组。给定字符串S,其所有后缀为S[0...n-1]S[1...n-1], ...,S[n-1](共n个)。将这些后缀按字典序排序后,记录排序后的后缀起始下标,即为后缀数组sa。示例字符串,其后缀数组为a(下标5)ana(下标3)anana(下标1)banana(下标0)na(下标4)nana(下标2)优势高效构建:倍增算法的时间复杂度为 O(n log n)。功能强大:支持快速查找子串、LCP等问题。适用场景。原创 2025-03-19 14:18:48 · 423 阅读 · 0 评论 -
平衡二叉树之SBT(Size Balanced Tree)原理
优点严格的平衡性保证,操作效率稳定。子树大小信息便于统计类查询(如排名、范围查询)。缺点实现复杂度较高,维护成本较大。旋转操作频繁可能影响性能。SBT适用于需要高效动态插入、删除及统计查询的场景(如数据库索引)。本文的Java实现展示了其核心逻辑,读者可进一步扩展其他功能(如排名查询)。原创 2025-03-23 05:30:00 · 288 阅读 · 0 评论 -
平衡二叉树之伸展树(Splay Tree)原理
伸展树是一种自平衡二叉搜索树自适应性:每次访问节点(查找、插入、删除)后,通过“伸展(Splay)”操作将该节点移动到根位置。无需额外存储平衡信息:不依赖AVL树的平衡因子或红黑树的颜色标记,仅通过旋转操作调整结构。局部性原理:频繁访问的节点会被移动到靠近根的位置,减少后续访问时间。优点实现简单,无需额外平衡信息。适合局部性强的访问场景。缺点单次操作可能较慢(但摊仍高效)。严格实时系统需谨慎使用。伸展树通过动态调整结构,在多数场景下提供高效操作。原创 2025-03-22 06:15:00 · 605 阅读 · 0 评论 -
树的高级应用:动态树(Dynamic Tree)原理
动态树(Dynamic Tree)是一种支持动态连接和高效路径查询的树形数据结构,广泛应用于网络连通性维护、路径统计等场景。本文详细讲解动态树的核心原理,并通过Java代码实现其核心功能。原创 2025-03-21 06:00:00 · 362 阅读 · 0 评论 -
树 -- 边分治原理
边分治通过分割边将树递归分解,适用于处理与边相关的路径问题。其关键在于选择平衡的分割边以提高效率。本文通过Java代码展示了边分治的实现细节,读者可根据具体问题调整处理逻辑。原创 2025-03-21 06:00:00 · 348 阅读 · 0 评论 -
单源最短路径算法 -- 迪杰斯科拉(Dijkstra)算法
简单易懂,实现简单。适用于有向图和无向图。时间复杂度较低,在稀疏图中表现较好。不能处理负权边。空间复杂度较高,毕竟需要存储所有顶点的最短距离。不适用于大规模图,效率较低。Dijkstra算法广泛应用于网络路由、地图导航、交通规划等领域,用于计算最短路径问题。然而,在实际应用中,需要注意算法的适用性和效率,根据具体问题选择合适的算法。原创 2024-06-08 11:07:30 · 1423 阅读 · 0 评论 -
多源最短路径算法 -- 弗洛伊德(Floyd)算法
总的来说,Floyd算法是一种计算图中所有顶点对之间最短路径的动态规划算法,它能够处理包含负权边的图,但不允许存在负权回路。适用于小型到中等规模稠密图的算法,尤其是在需要全局最短路径信息时。对于大型稀疏图或者单源最短路径问题,其他算法如Dijkstra算法可能更加合适。原创 2024-06-13 11:24:02 · 3901 阅读 · 0 评论 -
字符串处理 -- 前缀树(Trie)
在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。——维基百科有的人也之称为单词查找树,顾名思义,就是像查字典一样快速检索字符串的N叉树,其中每个节点代表一个字符串(通常是前缀)。在这种数据结构中,从根到某一节点的路径表示一个字符串,该字符串是沿途经过的所有字符的组合。前缀树,也被称为字典树、Trie树,是一种用于存储字符串的树形数据结构,也是哈希树的一种变种,特别适合处理具有共同前缀的字符串集合。原创 2024-04-13 13:09:45 · 2380 阅读 · 1 评论 -
常用算法 -- 回溯算法
总的来说,回溯算法是一种强大的问题解决工具,特别适合处理那些可以通过逐步构建解决方案来解决的问题。然而,由于其高时间复杂度和空间需求,在实际应用中可能需要进行适当的优化。通过剪枝、约束加强、启发式搜索等策略,可以有效提高回溯算法的效率,使其更好地应用于实际问题中。原创 2024-08-21 16:37:34 · 1228 阅读 · 0 评论 -
高级数据结构 -- 并查集(Disjoint-set data structure)
并查集是一种用于处理不相交集合的高效数据结构,主要用于解决元素分组和查询问题。可以用来判断图的连通性、找出图中的连通分量、网络连接、最近公共祖先查询等问题。原创 2024-04-15 22:03:01 · 1024 阅读 · 1 评论 -
经典排序 -- 非比较型的排序
不基于比较的排序算法主要有计数排序、基数排序等。核心思想是避免直接比较元素之间的大小关系,而是利用其他信息(如数值的分布特征或数字的位信息)来实现排序。计数排序是一种非比较型整数排序算法,其核心在于将输入的数据值转化为键,存储在额外开辟的数组空间中。计数排序在处理有限范围内的整数排序问题时,尤其是在数据分布密集的情况下,通常能够提供更好的内存效率。然而,如果数据范围很大或者数据分布非常稀疏,那么计数排序可能会导致辅助空间过大,从而不再节省内存。原创 2024-04-14 14:06:52 · 2155 阅读 · 1 评论 -
蓄水池抽样算法(Reservoir Sampling)
总的来说,蓄水池抽样算法是一种非常实用的随机抽样技术,尤其适用于资源受限和数据量大的场景。尽管存在一些局限性,但它的优点通常远远超过其缺点,使其成为处理大规模数据集时的一个很好的选择。原创 2024-08-26 10:54:29 · 1606 阅读 · 0 评论 -
BFPRT算法详解:最坏情况下O(n)时间复杂度找第k小元素
BFPRT算法展现了算法设计中平衡理论界限与工程实践的智慧结晶。虽然在实际应用中可能不如随机化算法快,但其确定性特征和严格的时间复杂度保证,使其在关键系统中仍具有不可替代的价值。理解这一算法,不仅能提升解决实际问题的能力,更能深化对分治策略和递归复杂度的认知。原创 2025-03-05 04:45:00 · 969 阅读 · 0 评论 -
AC自动机详解:高效多模式字符串匹配
AC自动机(Aho-Corasick算法)是一种用于多模式字符串匹配的高效算法,广泛应用于敏感词过滤、文本搜索等领域。本文将深入探讨AC自动机的工作原理、构建过程以及如何使用Java语言来实现这一强大的算法。原创 2025-03-07 07:00:00 · 1271 阅读 · 0 评论 -
Morris遍历:用O(1)空间复杂度实现二叉树遍历
Morris遍历算法通过巧妙的线索化方法,实现了二叉树遍历的O(1)空间复杂度!本文将深入解析其核心思想,并提供完整的Java代码实现,带你领略这一经典算法的精妙之处。原创 2025-03-03 15:18:03 · 276 阅读 · 0 评论 -
动态规划详解(一):原理、步骤
动态规划(Dynamic Programming, DP)是一种通过将复杂问题分解为重叠子问题,并记录子问题解来避免重复计算的算法设计方法。其核心思想是“记忆化存储”和“最优子结构”,常用于解决最优化问题(如最大值、最小值、最优路径等)。明确dp数组的含义。dp[i]表示前i个元素的最优解dp[i][j]表示从位置(0,0)到(i,j)的最优路径动态规划通过将问题分解为重叠子问题,显著降低了计算复杂度。掌握其核心原理和解题步骤后,可逐步攻克更复杂的算法问题。原创 2025-03-08 05:00:00 · 1570 阅读 · 0 评论 -
动态规划详解(三):背包问题的本质剖析与优化全步骤
核心心法0-1背包倒序遍历,完全背包正序遍历"选择"与"不选择"的决策贯穿所有背包问题解题步骤定义状态 → 推导方程 → 确定遍历顺序 → 空间优化扩展思考如何记录具体选择方案?多维费用背包如何处理?背包问题与图论的联系?推荐练习LeetCode 474. 一和零(二维费用背包)LeetCode 1049. 最后一块石头的重量 II(转换背包问题)LeetCode 1449. 数位成本和为目标值的最大数字(背包路径记录)原创 2025-03-10 04:15:00 · 1198 阅读 · 0 评论 -
【算法入门】暴力递归:从“简单粗暴”到“化繁为简”的算法基石
暴力递归是算法设计的起点,也是理解动态规划的基础。本文将通过经典案例解析暴力递归的核心思想、实现方法及优化方向,助你掌握这一“简单却强大”的算法思维!原创 2025-03-04 07:00:00 · 318 阅读 · 0 评论 -
Manacher算法详解:高效寻找最长回文子串
Manacher算法通过对称性利用和预处理技巧,高效解决最长回文子串问题。其核心在于维护回文半径数组和动态更新最远右边界,避免重复计算。掌握这一算法,可显著提升字符串处理效率。原创 2025-03-06 09:52:22 · 563 阅读 · 0 评论 -
动态规划详解(二):从暴力递归到动态规划的完整优化之路
动态规划(Dynamic Programming, DP)本质是一种通过**"聪明的穷举"解决问题的思想。它的核心是发现重叠子问题和最优子结构**,并通过存储中间结果避免重复计算。暴力递归 → 发现重复计算 → 记忆化搜索 → 推导状态转移 → 自底向上动态规划定义状态:明确dp数组的含义推导转移方程:分析状态间的关系初始化:设置边界条件确定遍历顺序:保证前置状态已计算输出结果:从dp数组中提取答案。原创 2025-03-08 05:15:00 · 1808 阅读 · 0 评论 -
高级数据结构 -- 优先队列
优先队列(Priority Queue)是一种特殊的队列数据结构,其中每个元素都关联一个“优先级”。不同于普通队列的先进先出(FIFO)规则,优先队列遵循优先级高者先出的原则。当多个元素具有相同优先级时,通常保留其插入顺序。优先队列通过堆结构高效管理动态数据优先级,理解其原理及实现有助于优化算法设计。实际开发中可依据需求选择自行实现或直接使用标准库。应用场景建议任务调度系统实时数据处理图算法(如最短路径)原创 2025-03-07 05:15:00 · 510 阅读 · 0 评论 -
动态规划详解(四):线性DP原理深度剖析
明确语义dp[i]或dp[i][j]的具体含义示例dp[i]表示以nums[i]结尾的最长上升子序列长度dp[i][j]表示与的最长公共子序列长度dp[i][0]:第i天持有股票的最大收益dp[i][1]:第i天不持有股票(非冷冻期)dp[i][2]:第i天处于冷冻期掌握线性DP的关键在于培养状态定义的直觉。建议从简单问题入手,逐步体会状态转移的内在规律,最终达到看到问题就能自然拆解状态的水平。原创 2025-03-11 05:15:00 · 727 阅读 · 0 评论 -
高级数据结构解密:单调栈原理
*单调栈(Monotonic Stack)**是一种特殊的栈数据结构,其元素始终保持单调递增或单调递减的特性。这种数据结构在解决特定类型的问题时表现出极高的效率,尤其是在处理"下一个更大元素"、"柱状图最大面积"等场景时,可以将时间复杂度优化至O(n)。原创 2025-03-04 07:00:00 · 990 阅读 · 0 评论 -
【算法详解】KMP算法:字符串匹配的极致优化
在字符串匹配问题中,暴力搜索(Brute Force)方法虽然简单直观,但效率较低。对于大规模数据的处理,我们需要一种更高效的算法——KMP(Knuth-Morris-Pratt)算法。本文将深入探讨KMP算法的工作原理、关键概念以及如何实现它。原创 2025-03-05 07:00:00 · 1074 阅读 · 0 评论 -
区间信息操作神器:线段树原理详解
线段树(Segment Tree)是一种基于二叉树设计的高级数据结构,专门用于高效处理区间查询与区间更新操作。它能够在O(log n)区间查询:求区间和、区间最大值/最小值等单点更新:修改某个位置的值区间更新:批量修改区间内的值(需配合延迟标记)分治思想:将大区间分解为小区间处理预处理加速:通过预先计算存储中间结果灵活扩展:支持多种合并逻辑与优化技巧重点练习建议实现区间最大值版本线段树添加延迟传播功能支持区间加尝试解决LeetCode 218. 天际线问题。原创 2025-03-10 04:15:00 · 1363 阅读 · 0 评论 -
动态规划进阶(八):状态压缩DP详解
状态压缩动态规划(State Compression DP)是一种利用位运算优化状态存储的DP实现技术。通过将多维状态压缩为整数的二进制位表示,可以显著减少空间复杂度,特别适用于处理包含大量状态但状态之间存在强关联性的问题。:当前已访问城市状态为state,最后停留在城市u的最短路径// 其中 prev_state = state ^ (1 << u)掌握核心思想:将状态信息编码为整数熟练位运算:灵活使用与、或、异或等操作问题建模能力:将实际问题转化为状态转移模型空间优化意识。原创 2025-03-14 03:15:00 · 944 阅读 · 0 评论 -
树结构算法精讲:点分治原理
点分治(Vertex Divide and Conquer)是处理树上路径问题的经典分治算法,主要解决以下类型问题:统计满足特定条件的路径数量(如路径长度等于K)查找树中最长合法路径检测特定路径特征(如包含特定颜色节点)时间复杂度优异:O(NlogN)处理大多数路径问题适用性强:可扩展处理各种路径统计问题代码模式统一:相似结构可套用解决不同问题LeetCode 437(路径总和III)原创 2025-03-19 05:45:00 · 884 阅读 · 0 评论 -
动态规划进阶(五):区间DP原理详解
明确语义dp[i][j]表示区间[i,j]的最优解示例:石子合并问题中,dp[i][j]表示合并第i到第j堆石子的最小代价1.定义区间状态→ 2.预处理前缀和→ 3.枚举分割点→ 4.合并子区间解高阶优化方向记忆化搜索实现四边形不等式优化状态压缩(如滚动数组)问题转换(将环形问题转为线性)原创 2025-03-12 06:00:00 · 1009 阅读 · 0 评论 -
动态规划进阶(六):树形DP原理详解
节点维度dp[u][s]表示节点u在状态s下的最优解常见状态选择/不选当前节点颜色标记(如红黑树着色问题)距离限制(如树的直径)dp[u][0]:不选节点u时的最大快乐值dp[u][1]:选择节点u时的最大快乐值int val;树形DP的解题关键定义合适的状态:通常与节点选择/属性相关设计正确的转移方程:考虑所有子节点状态组合掌握后序遍历特性:先处理子树再合并结果高阶扩展方向结合图论处理森林问题处理动态树结构(Link-Cut Tree)结合贪心思想优化状态转移。原创 2025-03-13 04:45:00 · 932 阅读 · 0 评论 -
Java实现基于DFA的敏感词过滤
本文实现的DFA敏感词过滤系统在1MB文本处理中达到120ms响应,可支持10万级敏感词库。通过优化算法和架构设计,可进一步提升系统性能,满足不同场景下的内容安全需求。原创 2025-03-11 05:15:00 · 1331 阅读 · 0 评论 -
动态规划进阶(七):数位DP原理详解
数位DP的核心在于将数字视为位序列处理1. 数位分解→ 2.状态设计→ 3.记忆化搜索→ 4.结果合成。原创 2025-03-14 07:45:00 · 586 阅读 · 0 评论 -
经典排序 -- 快速排序
快速排序是一种二叉树结构的交换排序方法,采用分治策略来对数据进行排序。选择基准值:通常选择序列的第一个或最后一个元素作为基准值。分区操作:重新排列序列,使得所有小于或等于基准值的元素都移到基准的左边,而所有大于基准值的元素都移到基准的右边。这一步完成后,基准值所在的位置就是其最终位置。递归排序:递归地将小于基准值的子序列和大于基准值的子序列再次进行快速排序。简而言之,就是将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值。再对左右两子序列分别递归排序。原创 2024-04-08 22:46:52 · 2902 阅读 · 0 评论 -
位运算简介与相关技巧
程序中的所有数在计算机内存中都是以二进制的形式储存的。即 0、1 两种状态,位运算就是直接对整数在内存中的二进制位进行操作。由于是底层运算,如果运用得当可以以降低空间需求和提高执行效率。原创 2024-04-06 22:45:13 · 708 阅读 · 1 评论 -
经典排序 -- 归并排序(Merge Sort)
归并排序(Merge Sort)是一种分治法(Divide and Conquer)的典型应用,它将待排序的数据分为两半,分别对这两半进行排序,然后将排序好的两半合并成一个有序的数组。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。归并排序,顾名思义先归(递归)后并(合并)的一种排序方式,将数组的数据分而治之。(归)将待排序的数据通过递归拆分到只有一个元素,那么它已经是有序的,直接返回。(并)将排序好的两半合并成一个最终的有序数组。时间复杂度低:归并排序的总体时间复杂度为。原创 2024-04-07 20:33:32 · 979 阅读 · 0 评论 -
基础数据结构 -- 图
本章主要介绍了图的两种结构。邻接矩阵表示方法:使用一个二维数组,其中行和列代表图中的顶点,矩阵中的元素表示顶点之间的边。适用场景:适合于稠密图,即图中的边数量接近于顶点数量的平方。优点:查询顶点之间是否存在边的时间复杂度为O(1)。缺点:空间复杂度高,为O(V^2),其中V是顶点数量;更新图(添加或删除顶点和边)的成本较高。邻接表表示方法:使用一个列表数组,每个顶点对应一个列表,列表中包含所有与该顶点相邻的顶点。适用场景:适合于稀疏图,即图中的边数量远少于顶点数量的平方。原创 2024-08-19 17:14:15 · 919 阅读 · 0 评论 -
基础数据结构 -- 堆
综上所述,堆是Java中一种非常重要的基础数据结构,它提供了高效的数据插入和删除操作,广泛应用于堆排序、top k问题等场景。理解堆的基本操作和应用,对于开发者来说非常有益,有助于更好地利用这一数据结构来解决实际问题。原创 2024-06-10 20:02:52 · 823 阅读 · 0 评论 -
基础数据结构 -- 队列
Java中的数据结构队列(Queue)是一种线性表,其特殊之处在于它只允许在表的后端进行插入操作,在表的前端进行删除操作。这种先进先出(FIFO,First In First Out)的结构类似于现实生活中的排队,最早等待的人将最先得到服务。Java中的队列是一种遵循先进先出(FIFO)原则的数据结构,与栈的后进先出(LIFO)特性形成对比。队列在Java的集合框架中具有重要地位,广泛应用于各种数据处理场景,如任务调度、缓冲数据等。原创 2024-06-08 23:41:05 · 927 阅读 · 0 评论 -
基础数据结构 -- 栈
Java中的栈是一种非常重要的数据结构,它遵循后进先出(LIFO)的原则,即最后进入的元素最先被取出。栈在Java中的应用非常广泛,从基本的算法实现到深层次的程序执行机制,都离不开栈的支持。原创 2024-06-08 22:39:36 · 1099 阅读 · 0 评论 -
基础数据结构 -- 数组
由于数组的大小固定的局限性,很多高级语言都会能够动态增长和缩减的数据结构。数组是计算机科学中一种基本的、重要的数据结构,用于存储一系列按顺序排列且类型相同的数据元素。定义和特性数组由固定数量的内存位置组成,每个位置可以存储一个特定类型的值(例如整数、浮点数或字符)。这些内存位置通过连续的索引进行访问,通常从0开始编号。数组在内存中是连续分配的,这使得元素可以通过其索引快速访问。优势高效的随机访问:可以直接通过索引在常数时间内访问任意元素。原创 2024-04-12 16:50:19 · 917 阅读 · 0 评论