首页
学习
活动
专区
圈层
工具
发布

字符串-后缀树和后缀数组详解

文章目录 后缀树 后缀数组 概念 sa[] rk[] height[] 例题 HDU-1403最长公共子串 洛谷P2408 不同子串个数 HDU-5769Substring 后缀树 建议先了解一下字典树...后缀树(suffix tree)就是把所有的后缀子串用字典树的方法建立的一棵树,如图: 其中根节点为空,还可以在叶子节点后用一个’$'符标识结束,从根节点出发就能到达所有的子串情况。...后缀数组和后缀自动机可以看作是对后缀树时间和空间上的优化,通过映射关系避免建树和提高树节点重复利用率。...后缀数组 概念 直接对后缀树构造和编程不太方便,而后缀数组(suffix array)就是更简单的替代方法。...,和最长公共前缀(Longest Common Prefix,LCP)相关。

5.4K10

hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq

当时,没有后缀数组 今天将是,事实上,自己的后缀阵列组合rmq或到,但是,题意理解的一个问题,再折腾了很长时间,,,, 此处简单解释下题目例子吧,希望对读者有帮助 以最后一组数据为例 myxophytamyxopodnabnabbednabbingnabit...6 0 9 9 16 16 19 19 25 25 32 32 37 前两行不解释,题目叙述非常清楚 从第三行,0 9 指的是第一个字符串是从第一行的字符串的0-9 左闭右开, 下面5行同样 继续看题目的正文叙述的例子...s[i]:-1; } for(k=1;k从1開始,由于0*2=0*/ { sort(sa,sa+...lastlen=r-l; } printf("%I64d %I64d\n",ansb,ansa); } return 0; } 再加一个rmq+后缀数组求最长公共前缀的模板吧...s[i]:-1; } for(k=1;k从1開始。

23620
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    生成平衡数组的方案数(前缀和+后缀和)

    题目 给你一个整数数组 nums 。你需要选择 恰好 一个下标(下标从 0 开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。...如果一个数组满足奇数下标元素的和与偶数下标元素的和相等,该数组就是一个 平衡数组 。 请你返回删除操作后,剩下的数组 nums 是 平衡数组 的 方案数 。...只有一种让剩余数组成为平衡数组的方案。 示例 2: 输入:nums = [1,1,1] 输出:3 解释:你可以删除任意元素,剩余数组都是平衡数组。...示例 3: 输入:nums = [1,2,3] 输出:0 解释:不管删除哪个元素,剩下数组都不是平衡数组。...解题 正反双向的奇偶前缀和都求出来 删除某个元素后,逆向的奇偶后缀和需要交换 class Solution { public: int waysToMakeFair(vector& nums

    47510

    后缀数组(一堆干货)

    从字符串的大小比较定义来看,S的开头两个位置后缀u和v进行比较的结果不可能是相等,因为u=v的必要条件len(u)=len(v)是不可能满足的。         ...简单地说,后缀数组是“排第几的是谁?”,名次数组是“你排第几?”。容易看出后缀数组和名次数组互为逆运算。...下面仅介绍倍增法构造后缀数组          最直接的方法,当然是把S的后缀都看作一些普通的字符串,按照一般字符串排序的方法对它们从小到大进行排序。         ...倍增算法正是充分利用了各个后缀之间的联系,将构造后缀数组的数组的最坏时间复杂度成功降到O(nlogn)。          对于一个字符串u,我们定义u的k-前缀 ?         ...LCPi(I,j)也就是后缀数组中第i个和第j个后缀的最长公共前缀的长度。

    1.5K30

    YbtOJ 535「后缀数组」相似子串

    注意到后缀转化后的数组同原串转化后的数组最多只会相差 10 位(每种字符第一次出现的位置有差异)。 于是我们以这 10 个位置为关键点,分段进行比较。...所以我们先对原串转化成的数组建立后缀数组,这样一来若要求解两个后缀转化成的数组的 \text{LCP},就可以直接 按关键点划分成若干段,将每一部分依次比较。...既然能够求出 \text{LCP},那么只要比较 \text{LCP} 的后一位就能比较两个不同后缀转化成的数组的字典序,也就可以将所有后缀转化成的数组做一遍排序。...然后,预先求出排名相邻的后缀的 \text{LCP}(类似于一般后缀数组中的 Height 数组)。 询问时在这个 “Height 数组” 上分别向左向右二分一下即可。...发现其实也并不需要使用后缀数组,求 \text{LCP} 直接 Hash+二分 也行,就是复杂度上多了只 \log。 Code /* 超!还卡哈希!

    46310

    2024-10-26:最长公共后缀查询。用go语言,给定两个字符串数组 wordsContainer 和 wordsQuery,

    用go语言,给定两个字符串数组 wordsContainer 和 wordsQuery,要对每个 wordsQuery[i] 找到一个与其有最长公共后缀的字符串。...对于 wordsQuery[2] = "xyz" ,wordsContainer 中没有字符串跟它有公共后缀,所以最长公共后缀为 "" ,下标为 0 ,1 和 2 的字符串都得到这一公共后缀。...• 对于每个查询字符串,初始化当前最长公共后缀的长度 (maxLen) 为0,和对应的字符串索引 (bestIndex)。...• 从当前查询字符串的尾部开始向前检查与当前 wordsContainer[j] 的后缀匹配。 • 计算两个字符串,从尾部开始的最大匹配长度。...• 若发现新的公共后缀长度大于 maxLen,则更新 maxLen 和 bestIndex 为当前字符串的索引。

    9220

    挑战程序竞赛系列(72):4.7高度数组(2)

    挑战程序竞赛系列(72):4.7高度数组(2) 传送门:POJ 3415: Common Substrings 题意: 公共子串:统计A和B长度不小于K的公共子串个数。...思路: 一开始想当然的求LCP数组,把LCP遍历一遍,大于K的,ans不断累加ans += lcp[i] - k + 1,但这只是一部分解,因为所求的只是相邻后缀的最长公共前缀。...一种直观的做法时,两个for循环,对于当前位置属于S的LCP时,向下找属于T的后缀,把每个后缀的最长对应公共前缀加一遍,但TLE了,此处需要利用单调性来简化时间复杂度。采用记忆化手段,用栈。...此处代码参考hankcs的代码,具体思路如下:对应于S的lcp,先不管三七二十一,贡献值都以最大的加,但我们知道,中间如果lcp变小,意味着后缀的公共前缀在不断减小,此时需要按照最小的算,只需要在贡献值上...针对T的lcp,同样处理。

    535100

    字典树和前缀树_前缀树和后缀树

    这样一来我们查询和插入可以一起完成(重点体会这个查询和插入是如何一起完成的,稍后,下文具体解释),所用时间仅仅为单词长度,在这一个样例,便是10。...图3 逐步构造后缀树 3.4、初窥门径 加入一个新的前缀需要访问树中已有的后缀. 我们从最长的一个后缀开始(图3中的BAN), 一直访问到最短的后缀(空后缀)....那么要构造下一个前缀BOOKK的后缀树的话, 只需要访问树中已存在的每一个后缀, 然后在它们的末尾加上K. 前4个后缀BOOK, OOK, OK和K都在叶节点上结束....图8 加上后缀指针(虚线)的ABABABC的后缀树 介绍一下如何创建后缀指针. 后缀指针的创建是跟后缀树的更新同步的. 随着我们从激活节点移动到结束节点, 我把每个新的叶节点的父亲的路径保存下来....;后缀数组和后缀树都是与字符串的后缀集合有关的数据结构;trie图中的后缀指针和后缀树中的后缀链接这两个概念及其一致。

    1.5K20

    LeetCode 算法 | 最长公共前缀?

    我们用子问题的解 lcpLeft 与 lcpRight 构造原问题的解 LCP(S_i \cdots S_j)LCP(Si⋯Sj)。...在字典树中,从根向下的每一个节点都代表一些键值的公共前缀。 但是我们需要找到字符串q 和所有键值字符串的最长公共前缀。...因为最长公共前缀不可能比某个字符串本身长 算法 最后的问题就是如何找到字典树中满足上述所有要求的最深节点。...我们从根节点遍历这颗字典树,直到因为不能满足某个条件而不能再遍历为止。 图 4....时间复杂度:预处理过程 O(S)O(S),其中 SS 数组里所有字符串中字符数量的总和,最长公共前缀查询操作的复杂度为 O(m)O(m)。 建立字典树的时间复杂度为 O(S)O(S)。

    87720

    【综合笔试题】两种强有力的字符串处理方式

    Tag : 「字符串哈希」、「二分」、「后缀数组」 给你一个字符串 s ,考虑其所有 重复子串 :即 s 的连续子串,在 s 中出现 次或更多次。这些出现之间可能存在重叠。...二分范围为 ,关键在于如何 check 函数,即实现「检查某个长度 作为最大长度,是否存在合法方案」。...;二分最大长度的复杂度为 ;整体复杂度为 空间复杂度: 后缀数组 另外一个较为进阶的做法是使用「后缀数组」,后缀数组有基于基数排序的倍增实现,复杂度为 ,也有基于 DC3 的...后缀数组包含几个核心数组: sa 数组:字典序排名为 的后缀是第几个; rk 数组:第 个后缀的排名是多少(不难发现 rk 与 sa 满足 ); height 数组:存储 与...的 LCP(最长公共前缀) 为何值。

    45420

    2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。实现 WordFilter 类:WordF

    答案2023-04-17: # 大体过程如下: 1.首先定义一个 Trie 树的结点类型 TrieNode,包含 nexts 数组和 indies 切片,其中 nexts 数组用于存储子节点,indies...3.实现 Constructor 方法,接受一个字符串数组作为参数,初始化 WordFilter 对象。在该方法内部,遍历单词数组,将每个单词插入正序和倒序的 Trie 树中。...4.实现 F 方法,接受两个字符串作为前缀和后缀参数,查找并返回满足要求的单词在原单词数组中的下标。该方法内部,分别在正序和倒序 Trie 树上匹配前缀和后缀,获取包含相应前缀和后缀的单词的下标集合。...- 查找函数 `F` 的时间复杂度为 O(M \log N),其中 M 是相应前缀和后缀所匹配到的下标集合的大小,N 是单词数组的长度。...# 空间复杂度: - 构造函数 `Constructor` 的空间复杂度为 O(NL^2),即正序和倒序两棵 Trie 树的总节点数。

    38320

    每日两题 T8

    分析 方法一:遍历后缀,hash检索 我们将数据存放在一个容器中,然后逐个拿出,检测拿出的字符串是否存在后缀在原容器中,如果存在,则删除,不存在则继续查看更小后缀,直至对比完该字符串,转而从容器拿出下一个元素...实现 Trie (前缀树)[2] 假设我们现在给定字符串数组:"A", "to", "tea", "ted", "ten", "i", "in", "inn" ? 这颗树怎么理解呢?...根节点无内容,读取第一个元素 A 加入这颗树,结果为:{A: {}},读取第二个字符串 to ,构造出 {t:{o:{}}, A:{}},继续读取第三个元素,构造出:{t:{o:{}, e: {a: {...的作用是一样的,区别在于传入参数的不同;2.第一个参数都是,指定函数体内this的指向;3.第二个参数不同,apply是传入带下标的集合,数组或者类数组,apply把它传给函数作为参数。...call从第二个开始传入的参数是不固定的,都会传给函数作为参数。

    49420

    2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[]

    答案2023-04-17:大体过程如下:1.首先定义一个 Trie 树的结点类型 TrieNode,包含 nexts 数组和 indies 切片,其中 nexts 数组用于存储子节点,indies 切片用于存储当前节点对应的单词在原单词数组中的下标...3.实现 Constructor 方法,接受一个字符串数组作为参数,初始化 WordFilter 对象。在该方法内部,遍历单词数组,将每个单词插入正序和倒序的 Trie 树中。...4.实现 F 方法,接受两个字符串作为前缀和后缀参数,查找并返回满足要求的单词在原单词数组中的下标。该方法内部,分别在正序和倒序 Trie 树上匹配前缀和后缀,获取包含相应前缀和后缀的单词的下标集合。...查找函数 F 的时间复杂度为 $O(M \log N)$,其中 $M$ 是相应前缀和后缀所匹配到的下标集合的大小,$N$ 是单词数组的长度。...空间复杂度:构造函数 Constructor 的空间复杂度为 $O(NL^2)$,即正序和倒序两棵 Trie 树的总节点数。

    39500
    领券