【问题标题】:What is the time complexity of breaking string into valid words?将字符串分解为有效单词的时间复杂度是多少?
【发布时间】:2016-08-21 07:06:45
【问题描述】:

问题是这样的:

给定一个英语词典(实现为哈希图(单词 -> 含义))和一个不带空格的字符串,输出所有可能的有效英语单词组合,当它们组合时,再现输入字符串。

问题可以用递归/动态规划来解决,但是在分析时间复杂度的时候,我一头雾水:

  1. 想象字典包含所有可能的字符排列(每个字符序列都是一个有效的单词),然后给定字符串,对于 2 个字符之间的每个位置,您可以选择是否插入空格,有n-1 个这样的位置,所以有 2^(n-1) 个可能的结果。生成这些结果的任何算法的复杂度必须至少为 O(2^n)。

  2. 我可以使用动态规划算法来做到这一点。假设 result[i] 是子串 i..N 的可能拆分,计算 result[j]:

    for k in range j+1 to N: if s[j:k] is a valid word: merge the word in the result[k]

    由于我们将result[N]计算回result[0],并且这些计算中的每一个都需要O(N)(因为我们依赖的子问题已经计算过了),所以时间复杂度应该是O(N^2) .

为什么我可以从两种推理中得到不同的结论,哪种是正确的?

【问题讨论】:

  • 我猜字典的大小必须以某种方式包含在时间复杂度中,因为它是输入的一部分。
  • 复杂度取决于字典的内容;例如,假设字典仅包含 5 个字母单词,而最多只有一种拆分字符串的方法。并且很容易找到分裂。您的推理 1 给出了最坏的情况。
  • 您对(1)的分析是正确的;对于(2)这是错误的。后一种情况的问题是,可能有很多(不仅仅是一种)方法可以将剩余部分 s[k+1:N] 拆分为单词,因此 merge the word into result[k] 必须花费(至少)与这样做的方法数量成正比的时间.
  • (OTOH,如果您只想找到 some 将字符串拆分为单词的特定方法(可以选择最大化某个分数),那么您的 (2 ) 可以在 O(n^2) 时间内完成此操作,假设您使用的数据结构允许 O(1) 中的“添加给定字符以开始”和“测试当前字符串是否在字典中”操作。)
  • 如果我只想要由最少的单词组成的解决方案怎么办?我必须计算所有解决方案并选择最小的解决方案还是另一种方式?

标签: algorithm time-complexity


【解决方案1】:

除了输入字符串n 的大小之外,您还应该引入一个额外的参数r 来表示结果的大小,并在您的分析中使用它。在这种情况下,“结果的大小”类似于每个有效组合中单词数的总和。

在您对算法的描述中,您掩盖了如何将中间结果合并到循环体中。您隐含地假设这可以在恒定时间内完成。但是,正如您所指出的,这会导致矛盾的结果。

如果将算法分成两个阶段,分析会更简单:

  • 在第一阶段,您构建一个数据结构,指示单词可以嵌入到字符串中的位置。这可以在Θ(n^2)时间完成,假设您可以检查每个子字符串是否是摊销常数时间内的单词。

  • 在第二阶段,您遍历此数据结构以输出单词组合列表。这可以在输出大小的线性时间内完成,Θ(r)

所以总的来说,这个算法的时间复杂度为Θ(n^2 + r)

注意:为了形式上正确,您还应该考虑阅读英文单词列表所需的时间。如果你想解决这个问题,你可以引入一个额外的变量 d 并在时间复杂度中添加一个 + d 项。

另外:这个界限的n^2部分可以通过使用Aho-Corasick algorithm来查找所有匹配的子字符串而不是在哈希表中查找每个子字符串来改进。

【讨论】:

  • 您能否详细说明如何使用 Aho_Corasick 算法查找子字符串?我认为该算法是针对不同的问题而设计的,例如从abcd 中查找单词abcbcd。但是这个断词问题不允许单词重叠。我错过了什么吗?
  • @NeoWang:Aho-Corasick 算法的输出会告诉你在什么位置找到了哪些单词。您可以按位置排序该列表。然后,抓住一个从位置 0 开始的单词。说它是“foo”。现在,查看列表是否包含从位置 3 开始的单词(即开始位置加上单词长度),依此类推。而且,顺便说一句,Aho-Corasick 算法比仅仅“在 'abcd' 中查找 'abc' 和 'bcd' 更有用。它可以在一次文档中找到许多单词或短语的出现。病毒扫描程序使用非常相似的东西来快速检查可执行文件。
猜你喜欢
  • 2023-04-07
  • 2012-12-19
  • 2021-05-04
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 2014-01-03
相关资源
最近更新 更多