将字符串分解为有效单词的时间复杂度是多少?

时间:2016-04-27 06:36:13

标签: algorithm time-complexity

问题是这样的:

  

给定一个英语字典(实现为散列映射(word - >含义))和不带空格的字符串,输出有效英语单词的所有可能组合,当组合时,重现输入字符串。

这个问题可以通过递归/动态编程解决,但在分析时间复杂度时,我很困惑:

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

  2. 我可以使用动态编程算法来执行此操作。假设result [i]是子串i..N的可能分裂,以计算结果[j]:

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

    由于我们将结果[N]计算回结果[0],并且这些计算中的每一个都采用O(N)(因为我们依赖的子问题已被计算),时间复杂度应为O(N ^ 2)

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

注意:要正式更正,您还应该考虑阅读英文单词列表所需的时间。如果您想对此进行说明,则可以引入其他变量d并在时间复杂度中添加+ d字词。

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