问题描述
void permute(String str,int l,int r) {
if (l == r)
System.out.println(str);
else {
for (int i = l; i <= r; i++) {
str = swap(str,l,i);
permute(str,l+1,r);
str = swap(str,i);
}
}
}
打印一个排列是递归树的深度需要线性时间复杂度。
解决方法
但是 permute
在 for
循环内被调用:
- 第一次调用
n
次; - 第二次调用
n-1
次(总共n * (n-1)
次); - 下一个递归级别 (
n-2
) 的n * (n-1) * (n-2)
次 - ...
- 最后一级 (
n!
) 一次
,
由于您使用的是 Java 并且 Java String
是不可变的,因此每次调用 permute
时,您都会再构造 2 个新字符串:
str = swap(str,i,l);
...
str = swap(str,l,i);
因此,您构造了与调用 permute
一样多的字符串,然后是 O(n!)。垃圾收集器可能会回收未使用的回收器,但由于您无法真正控制 GC,因此在最坏的情况下不会回收任何东西。
您的空间复杂度与您管理空间的方式有关。
如果你想要线性空间,你必须使用提供可变字符串的 Java StringBuffer
。
一般来说,打印不计入空间复杂度(参见 does-space-complexity-analysis-usually-include-output-space),因此您的实现使用 O(n!) 空间复杂度的事实是由于您的实现的内部结构(这里是不可变的 {{ 1}} 秒)。
,要获得“O(n)”空间复杂度,您必须使用可变数组,因为在 Java 中 String
是不可变对象。
public static String permute(String str) {
char[] arr = str.toCharArray();
permute(arr,arr.length - 1);
return new String(arr);
}
private static void permute(char[] arr,int l,int r) {
//...
}