关于string:在线性时间内查找两个序列之间的第一个元素匹配?

Find first element match between two sequences in linear time?

假设我们有两个序列x=x_i:i元素[1,m]和y=y_i:i元素[1,n]和有序字母表。有没有可能找到最小的(如果有的话)对(i,j),这样x_i=y_j?

琐碎的o(n^2)时间o(1)空间算法只是让您将两个序列中的每个元素进行比较,以跟踪从序列开始的最小距离差。

一个O(n logn)时间O(n)空间算法只对序列进行排序和比较,同时保持对最小/最大元素的跟踪。

不过,我想不出线性时间算法,我也不确定这个问题会被称为什么。


首先,注意,它可以在O(max{m,n}log(min{m,n}))中完成,只对较小的列表进行排序,并在迭代较大的列表时对其使用二进制搜索。

此外,还可以使用哈希表对一个列表进行索引,以对x_i->min{j, x_j = x_i }—这需要预期的线性时间和空间。然后,简单地迭代另一个列表,在表中查找y_i,同时保持到目前为止找到的最小值。

这在O(N)空间和时间的总和在平均情况下。

伪代码:

1
2
3
4
5
6
7
8
9
10
table = {}
for each element x_i in x in ascending order of i:
  if x_i is not in table:
    table[x_i] = i
best_pair = (-1,-1)
for each element y_j in y:
  if y_j in table:
    if (table[y_j],j) is"better" than best_pair:
      best_pair = (table[y_j], j)
return best_pair

我非常肯定,它与元素的区分问题太相似,无法在不使用散列的情况下克服欧米伽(nlogn)边界,但我没有想到任何证据。


一种选择是建立一个大小为σ的表,其中σ是您的字母表,它将每个符号与它在字符串x中所占的第一个位置相关联。然后您可以迭代x,并为每个字符在表中记录该字符在x中的第一个位置。然后,您可以对字符串y进行一次传递,对于y中的每个字符,请查阅表以查找该字符第一次出现在字符串x中的时间。您在问题中没有提到如何定义"最小"对(词典编纂顺序)?最小化I+J?还有别的吗?)但是您应该能够生成所有可能的对,然后在线性时间内取它们的最小值。

总的来说,这需要时间o(n+σ)和使用空格o(σ),所以如果字母表不太大,这是相当快的。如果您的字母表很大,只需使用一个哈希表,这样就可以得到O(n)时间和O(n)空间。


O(N+M)算法:

  • 从i=0和j=0开始
  • 如果x[i]
  • 如果x[i]>y[j]j++
  • 如果x[i]==y[j]=>你找到了它

显然,您还需要检查数组边界。