【发布时间】:2016-08-21 07:06:45
【问题描述】:
问题是这样的:
给定一个英语词典(实现为哈希图(单词 -> 含义))和一个不带空格的字符串,输出所有可能的有效英语单词组合,当它们组合时,再现输入字符串。
问题可以用递归/动态规划来解决,但是在分析时间复杂度的时候,我一头雾水:
想象字典包含所有可能的字符排列(每个字符序列都是一个有效的单词),然后给定字符串,对于 2 个字符之间的每个位置,您可以选择是否插入空格,有n-1 个这样的位置,所以有 2^(n-1) 个可能的结果。生成这些结果的任何算法的复杂度必须至少为 O(2^n)。
-
我可以使用动态规划算法来做到这一点。假设 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) 中的“添加给定字符以开始”和“测试当前字符串是否在字典中”操作。)
-
如果我只想要由最少的单词组成的解决方案怎么办?我必须计算所有解决方案并选择最小的解决方案还是另一种方式?