[英]Running time of permutation function
我的书为一个函数提供了以下代码,该函数计算一串独特字符的所有排列(见下面的代码),并说运行时间是O(n!),“因为有n!排列。”
我不明白他们如何计算运行时间为O(n!)。 我认为它们的意思是“n”是原始字符串的长度。 我认为运行时间应该是O((n + 1)XY),因为getPerms函数将被调用(n + 1)次,而X和Y可以表示外部和内部for循环的运行时间分别。 有人可以向我解释为什么这是错的/本书的答案是对的吗?
谢谢。
public static ArrayList<String> getPerms(String str)
{
if (str == null)
return null;
ArrayList<String> permutations = new ArrayList<String>();
if (str.length() == 0)
permutations.add("");
return permutations;
char first = str.charAt(0); //first character of string
String remainder = str.substring(1); //remove first character
ArrayList<String> words = getPerms(remainder);
for (String word: words)
{
for (i = 0; i <= word.length(); i++)
{
String s = insertCharAt(word, first, i);
permutations.add(s)
}
}
return permutations;
}
public static String insertCharAt(String word, char c, int j)
{
String start = word.substring(0, i);
String end = word.substring(i);
return start + c + end;
}
资料来源:破解编码面试
从我们的直觉来看,很明显没有现有算法可以生成N个项目的排列,这些项目的性能优于O(n!),因为有n个! 可能性。
您可以将递归代码缩减为递归方程,因为gePerm(n)
其中n是n长度的字符串将调用getPerm(n-1)
。 然后,我们使用它的所有值返回并放置一个循环N次的内部循环。 所以我们有
P n = nP n-1
P 1 = 1
很容易看出P n = n! 通过伸缩方程。
如果你很难想象我们如何提出这个等式,你也可以这样思考
ArrayList<String> words = getPerms(remainder);
for (String word: words) // P(n-1)
{
for (i = 0; i <= word.length(); i++) // nP(n-1)
{
String s = insertCharAt(word, first, i);
permutations.add(s)
}
}
N
元素的排列计数是N * (N - 1) * (N - 2) * ... * 2 * 1
,即N!
。
第一个字符可以是N
字符中的任何一个。 下一个字符可以是剩余的N - 1
字符之一。 现在我们已经有了N * (N - 1)
可能的案例。
所以,继续我们将在每一步都有N * (N - 1) * (N - 2) * ...
个案。
导致N
元素的排列计数为N!
,那么没有一个实现可以比N!更快地排列长度为N
的数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.