小编典典

Google搜索结果:如何找到包含所有搜索关键字的最小窗口?

algorithm

该算法用于查找包含所有搜索关键字的最小代码段的复杂性是什么?


阅读 174

收藏
2020-07-28

共1个答案

小编典典

如前所述,该问题可以通过一个相当简单的算法解决:

只需从头开始顺序浏览输入文本,然后检查每个单词:是否在搜索键中。如果单词在键中,请将其添加到我们称为 “当前块
”的结构的末尾。当前块只是单词的线性序列,每个单词都带有在文本中找到它的位置。当前块必须保持以下 属性
:当前块中的第一个单词必须在当前块中出现一次,并且只能出现一次。如果将新单词添加到“当前块”的末尾,并且违反了上述属性,则必须从该块中删除第一个单词。此过程称为
标准化 当前块。规范化是一个潜在的迭代过程,因为一旦您从块中删除了第一个单词,新的第一个单词也可能会违反The
Property,因此您也必须将其删除。等等。

因此,当前块基本上是一个FIFO序列:新字到达右端,并通过规范化处理从左端删除。

解决该问题所需要做的就是浏览文本,维护“当前块”,并在必要时对其进行规范化,以使其满足The
Property。您所构建的包含所有关键字的最短代码块就是问题的答案。

例如,考虑文字

CxxxAxxxBxxAxxCxBAxxxC

并使用关键字A,B和C。浏览文本,您将构建以下块顺序

C
CA
CAB - all words, length 9 (CxxxAxxxB...)
CABA - all words, length 12 (CxxxAxxxBxxA...)
CABAC - violates The Property, remove first C
ABAC - violates The Property, remove first A
BAC - all words, length 7 (...BxxAxxC...)
BACB - violates The Property, remove first B
ACB - all words, length 6 (...AxxCxB...)
ACBA - violates The Property, remove first A
CBA - all words, length 4 (...CxBA...)
CBAC - violates The Property, remove first C
BAC - all words, length 6 (...BAxxxC)

我们构建的最佳块的长度为4,在这种情况下就是答案

CxxxAxxxBxxAxx CxBA xxxC

该算法的确切复杂度取决于输入,因为它决定了规范化过程将进行的迭代次数,但是忽略规范化的复杂度将是琐碎的O(N * log M),其中N,文本中的单词M数和关键字数,以及O(log M)是检查当前单词是否属于关键字集的复杂性。

话虽如此,我不得不承认我怀疑这可能不是您所需要的。既然您在标题中提到了Google,则可能是您在帖子中提出的问题说明不完整。也许在您的情况下文本被索引了?(有了索引,上述算法仍然适用,只是效率更高)。也许有一些棘手的数据库来描述文本并允许使用更有效的解决方案(例如无需查看整个文本)?我只能猜测,而您不是在说…

2020-07-28