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

Algorithm 将字符串分解为有效单词的时间复杂度是多少?,algorithm,time-complexity,Algorithm,Time Complexity,问题是这样的: 给定一个英语词典(作为hashmap(word->means)实现)和一个不带空格的字符串,输出所有可能的有效英语单词组合,组合后会重现输入字符串 这个问题可以通过递归/动态规划来解决,但在分析时间复杂性时,我感到困惑: 假设字典包含每个可能的字符排列(每个字符序列都是有效的单词),然后给定字符串,对于2个字符之间的每个位置,您可以选择是否插入空格,有n-1个这样的位置,因此有2^(n-1)个可能的结果。生成这些结果的任何算法的复杂度必须至少为O(2^n) 我可以使用动态规划算法

问题是这样的:

给定一个英语词典(作为hashmap(word->means)实现)和一个不带空格的字符串,输出所有可能的有效英语单词组合,组合后会重现输入字符串

这个问题可以通过递归/动态规划来解决,但在分析时间复杂性时,我感到困惑:

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

  • 我可以使用动态规划算法来实现这一点。假设结果[i]是子串i..N的可能拆分,以计算结果[j]:

    j+1到N范围内的k的
    :
    如果s[j:k]是有效词:
    将结果中的单词合并[k]

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


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

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

    在对算法的描述中,您忽略了如何将中间结果合并到循环体中。您隐含地假设这可以在恒定的时间内完成。然而,正如您所注意到的,这导致了一个矛盾的结果

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

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

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

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

    注意:在形式上要正确,你也应该考虑阅读英语单词表所需的时间。如果您想说明这一点,可以引入一个附加变量
    d
    ,并在时间复杂度中添加一个
    +d


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

    我猜字典的大小必须以某种方式包含在时间复杂度中,因为它是输入的一部分。复杂度取决于字典的内容;例如,假设字典只包含5个字母的单词,那么最多只有一种方法可以拆分字符串。这是很容易找到的分裂。最坏的情况由你的推理1给出。你对(1)的分析是正确的;这是错误的。后一种情况下的问题是,可能有很多(不仅仅是1)方法将剩余的
    s[k+1:N]
    拆分为单词,因此
    将单词合并为结果[k]
    需要(至少)与拆分方法数量成比例的时间。(OTOH,如果您想找到将字符串拆分为单词的特定方法(可选地,使一些分数最大化),那么您(2)中的DP可以在O(n^2)时间内完成这项工作,假设您使用的数据结构允许O(1)中的操作“添加给定字符开始”和“测试当前字符串是否在字典中”。)如果我只想要由最少的单词组成的解,我该怎么办?我必须计算所有的解并选择最小的一个吗?还是另一种方法?你能详细说明如何使用Aho_Corasik算法来查找子字符串吗?我认为该算法是为不同的问题设计的,比如查找单词
    abc
    bcd
    来自
    abcd
    。但是这个分词问题不允许单词重叠。我遗漏了什么吗?@NeoWang:Aho-Corasick算法的输出会告诉你在什么位置找到了哪些单词。你可以按位置排序该列表。然后,抓取一个从位置0开始的单词。说它是“foo”现在,看看列表中是否包含从位置3开始的单词(即开始位置加单词长度),依此类推。顺便说一下,Aho-Corasick算法比“在‘abcd’中查找‘abc’和‘bcd’。它可以在文档的一次传递中找到许多单词或短语。病毒扫描程序使用非常类似的方法快速检查可执行文件。”。