【发布时间】:2017-05-28 10:05:28
【问题描述】:
给定一组不同的数字,返回所有可能的排列。
例如,[1,2,3] 有以下排列:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
我的迭代解决方案是:
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
result.add(new ArrayList<>());
for(int i=0;i<nums.length;i++)
{
List<List<Integer>> temp = new ArrayList<>();
for(List<Integer> a: result)
{
for(int j=0; j<=a.size();j++)
{
a.add(j,nums[i]);
List<Integer> current = new ArrayList<>(a);
temp.add(current);
a.remove(j);
}
}
result = new ArrayList<>(temp);
}
return result;
}
我的递归解决方案是:
public List<List<Integer>> permuteRec(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums == null || nums.length == 0) {
return result;
}
makePermutations(nums, result, 0);
return result;
}
void makePermutations(int[] nums, List<List<Integer>> result, int start) {
if (start >= nums.length) {
List<Integer> temp = convertArrayToList(nums);
result.add(temp);
}
for (int i = start; i < nums.length; i++) {
swap(nums, start, i);
makePermutations(nums, result, start + 1);
swap(nums, start, i);
}
}
private ArrayList<Integer> convertArrayToList(int[] num) {
ArrayList<Integer> item = new ArrayList<Integer>();
for (int h = 0; h < num.length; h++) {
item.add(num[h]);
}
return item;
}
根据我的迭代解决方案的时间复杂度(大哦)是:n * n(n+1)/2~ O(n^3)
我无法弄清楚递归解决方案的时间复杂度。
谁能解释两者的复杂性?
【问题讨论】:
-
n 个元素的排列数是 n!,所以一个算法产生所有 n!排列的时间复杂度为 O(n!)。
-
对于递归和迭代?
-
@OJASJUNEJA 是的。对于这个问题,这是可以想象的最佳运行时间。想象一下,如果你有一个魔法发生器,它每 1 秒吐出一个排列。您仍然需要等待
n!秒才能完成此生成器,因为存在n!排列。 -
方法无所谓。如果 n 充分大于 k,则 n! > k^n,所以时间复杂度是 O(n!)。少数几个大于 n 的表达式之一!是一个double exponential,比如n^(n^n)。
-
复杂度为
O(n!) == O(n**(n + 1/2)*exp(-n))见en.wikipedia.org/wiki/Stirling's_approximation
标签: java algorithm recursion time-complexity