【发布时间】:2018-07-19 15:35:32
【问题描述】:
从长度为 n 的给定字符串 S 构建数据结构,支持快速查询以检查输入字符串是否长度为 J m 是 S 的子序列。
S是静态字符串,数据结构的预处理时间可以忽略。
要求:
- 空间消耗应该是线性的
O(n) -
subsequence(J)的运行时间应该取决于 m - 不一定是O(m),但越快越好。
什么是子序列?
A 是 B 的子序列,如果 A 可以通过从 B 中删除零个或多个字符来构造.即ABA 是ADBDBAC 的子序列
我尝试了什么
支持Subsequence(J) 查询的数据结构存储从S 中的每个字母到字母表中每个字母在S 中下一个出现的指针。 p>
令 A 为长度为 n + 1 的数组。 A 包含散列在字母表 σ 上的哈希表。哈希表中的每个键值对 (k,v) 都包含一些字母 k 作为键,它的下一次出现作为值 v。
哈希表 A_0 包含字母表中每个字母的第一次出现。
-
哈希表 A_1 包含字母在 S_0 的第二次出现的索引以及其他字母的第一次出现。
哈希表 A_2 包含字母 S_1 和 S_2 的第二次出现的索引,假设它们是不同的字母 -否则 A_2 将在 S_1 处包含字母的第三个索引 - 以及其他字母的第一次出现,依此类推...
例子:如果T是B C A D F B,¥代表散列表A_0,代表一个Ø null指针,数据结构看起来像:
|0 1 2 3 4 5
|¥ B C A D B
A|3 3 3 Ø Ø Ø
B|1 5 5 5 5 Ø
C|2 2 Ø Ø Ø Ø
D|4 4 4 4 Ø Ø
字母表 \sigma 是由 T 中的字母构成的,并且是静态的。因此,可以使用完美哈希(FKS)。
运行查询要使用字符串 J 执行 Subsequence(J) 查询,我们在 中查找第一次出现 J_0 的 A-index >S 使用 A_0。
在示例中,我们可以查询Subsequence("BAB") 来测试BAB 是否是子序列:
* 在返回索引 1 的列 0 中查找 B
* 在返回索引 3 的第 1 列中查找 A
* 在返回索引 5 的第 3 列中查找 B
只要我们不传递空指针,字符串就是子序列。哈希查找需要固定时间,我们最多只能执行 |J| 个,运行时间为 O(|J|)。
空间消耗为O(|J|·|S|)
【问题讨论】:
-
你尝试了什么?
-
字母的大小是不变的吗?
-
@wp78de 我的第一次发帖很糟糕 - 我查看了文档并添加了我尝试过的部分。
-
@pkpnd 是的,字符串 S 是在我们构建数据结构之前给出的。
-
@DannyDannyDanny 这不是我问的。有多少种不同的字母?不管 S 有多长,S 是否可以包含所有不同的字符?
标签: string algorithm data-structures subsequence