【发布时间】:2016-08-24 14:01:11
【问题描述】:
考虑以下代码。
public class Permutations {
static int count=0;
static void permutations(String str, String prefix){
if(str.length()==0){
System.out.println(prefix);
}
else{
for(int i=0;i<str.length();i++){
count++;
String rem = str.substring(0,i) + str.substring(i+1);
permutations(rem, prefix+str.charAt(i));
}
}
}
public static void main(String[] args) {
permutations("abc", "");
System.out.println(count);
}
}
这里的逻辑,我认为遵循的是-它将字符串的每个字符视为可能的前缀并置换剩余的 n-1 个字符。
所以按这个逻辑递归关系就出来了
T(n) = n( c1 + T(n-1) ) // ignoring the print time
这显然是 O(n!)。但是当我使用计数变量来查看 wather 算法真的按 n 顺序增长时,我发现了不同的结果。
对于 count++ 的 2 长度字符串(在 for 循环内)运行 4 次,对于 3 长度字符串,count 的值为 15,对于 4 和 5 长度字符串,其值为 64 和 325。
这意味着它比 n! 更糟糕。那么为什么它说这个(以及产生排列的类似算法)在运行时间方面是 O(n!)。
【问题讨论】:
-
为什么?你能解释一下吗?
-
n!是排列的数量,如果你在if的第一个块内增加count,你会得到n!,但你实际计算的是排列的数量调用大于n!的permutations。 -
@Holt 但这些调用也负责增加算法的运行时间。为什么我们不应该考虑这一点。我知道只能有n!排列,如果我们在 if 块中增加计数,它肯定会打印 n!。
-
@Holt 你的意思是虽然它看起来比 n 大!但它肯定是 n! 的常数倍数。这就是为什么我的计数值更高...您能否将您的陈述建立在一些事实/证明的基础上,即这里的计数值肯定是 n 的常数倍!并且不依赖于 n
-
Holt 的回答是正确的,但实际上排列函数需要 O(N * N!) 时间,或 O((N+1)!) 时间,因为它需要 O(N) 时间打印每个字符串。
标签: algorithm time-complexity permutation