我给出了以下解决方案(我认为解决方案没问题,不确定),但无法分析它的时间复杂性。
如果有人有兴趣,这就是问题:(如果没有,请跳到代码中):
您的输入是D
- 一组单词,s
- 一个没有空格的字符串。编写一种方法来计算s
的合法分工数,以便定义合法分工,使得s
分区的所有单词都在D
中。例如,如果D
包含{run,time,runtime}
,那么对于s="runtime"
,答案应为2:第一个是空分区(意思是单词runtime
),第二个是一个是将s
分区为"run"
和"time"
这是我的解决方案(伪):
int CountPartitions(string s)
{
if (s.Length == 0)
return 1;
int result = 0;
for (int i = 0; i < s.Length ; ++i)
{
string prefix = s.substring(0,i);
if (D.cotains(prefix))
{
result += CountPartitions(s.substring(i+1,s.Length));
}
}
return result;
}
我看到它的方式,函数的时间复杂度由下式给出:
T(n) = T(n-1)+T(n-2)+...+T(1)
假设查询字典可以在恒定时间内完成,T(1)
是常数,我不知道如何解决这个等式。
答案 0 :(得分:0)
您的算法和递归方程似乎是正确的。
要计算时间复杂度,请计算T(1)
扩展表达式中显示的T(n)
的数量。
让N(n)
成为T(1)
在展开后T(n)
显示的数量。
例如T(3) = T(2) + T(1) = T(1) + T(1)
所以N(3) = 2
我将使用induction为所有N(n) = 2^(n-2)
n >= 2
n = 1: T(1) = T(1) => N(1) = 1
n = 2: T(2) = T(1) => N(2) = 1 = 2^(2-2)
n = 3: T(3) = 2*T(1) => N(3) = 2 = 2^(3-2)
所以让N(k) = 2^(k-2)
对所有2 < k <= n
都正确无误:
T(n+1) = T(n) + T(n-1) + ... + T(1)
=> N(n+1) = N(n) + ... N(1)
= 2^(n-2) + 2^(n-3) + ... 2^(n-n) + 1
= ( 2(n-1) - 1 ) + 1
= 2^(n-1)
所以,现在我们知道N(n) = 2^(n-2)
是正确的。因此,算法的复杂度为Θ(2 ^ n)。
如果您只想要上限或下限,可以使用技巧:
n/2 * T(n/2) <= T(n) <= (n-1) * T(n-1)
这为您提供了上限O((n-1)!)和下限Ω(n ^(log n))。