Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 查找线性时间内两个序列之间的第一个元素匹配?_String_Algorithm_Big O_Time Complexity - Fatal编程技术网

String 查找线性时间内两个序列之间的第一个元素匹配?

String 查找线性时间内两个序列之间的第一个元素匹配?,string,algorithm,big-o,time-complexity,String,Algorithm,Big O,Time Complexity,假设我们有两个序列x={x_i:i elem[1,M]}和y={y_i:i elem[1,N]},具有有序字母表。有没有可能找到最小的(如果有的话)对(i,j),使得x_i=y_j 平凡的O(n^2)时间O(1)空间算法只是让你将序列中的每个元素一起比较,并跟踪从序列开始的最小距离差 O(n logn)时间O(n)空间算法只是对序列进行排序和比较,同时保持对最小/最大元素的跟踪 但是我想不出一个线性时间算法,我也不确定这个问题会被称为什么。一个选项是建立一个大小为∑|的表,其中∑是你的字母表,它

假设我们有两个序列x={x_i:i elem[1,M]}和y={y_i:i elem[1,N]},具有有序字母表。有没有可能找到最小的(如果有的话)对(i,j),使得x_i=y_j

平凡的O(n^2)时间O(1)空间算法只是让你将序列中的每个元素一起比较,并跟踪从序列开始的最小距离差

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


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

一个选项是建立一个大小为∑|的表,其中∑是你的字母表,它将每个符号与它在字符串x中占据的第一个位置相关联。然后可以迭代x,并为每个字符记录该字符在表中x中的第一个位置。然后可以对字符串y进行传递,对于y的每个字符,请查阅表格以查找该字符第一次出现在字符串x中的时间。您在问题中没有提到如何定义“最小”对(字典顺序?最小化i+j?其他什么?),但您应该能够生成所有可能的对,然后在线性时间内取最小值


总的来说,这需要时间O(n+|∑|)和使用空间O(|∑|),所以如果你的字母表不是太大,这是相当快的。如果你的字母表很大,只需要使用一个哈希表,结果是O(n)时间加O(n)空间。

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

此外,您可以使用哈希表将一个列表索引为成对的
x_i->min{j,x_j=x_i}
——这需要预期的线性时间和空间。
然后,只需迭代另一个列表,并在表中查找
y_i
,同时保持迄今为止找到的最小值

在平均情况下,这在O(n)空间和时间内总计

伪代码:

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)边界,这与太相似了,但我没有想到任何证据。

O(n+m)算法:

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

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

它可以在O(max{m,n}log(min{m,n}))中完成,只对较小的列表进行排序,并在迭代较大的列表时对其使用二进制搜索。我很确定这与元素区分性问题太相似,无法克服nlogn边界(除非允许使用散列且价格便宜),数组没有排序。在最新版本中,我对数组对(I,j)的排序不明确,但最初我对任何通用度量都感兴趣。我喜欢你的答案,因为它处理的是一个小字母表的情况,它与amit更一般的答案非常相似,可以处理任意字母表大小的序列。这就是我要找的名字,谢谢!您的算法和templatetypedef都解决了这个问题,但当您的字母表大小为无限大时(例如,您有一个字符串序列!),您的算法会更普遍地解决这个问题。