[英]What is the time complexity of this recursive function that checks for a permutation?
[英]Time Complexity of permutation function
給定一組不同的數字,返回所有可能的排列。
例如,[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)
我無法計算出我的遞歸解決方案的時間復雜度。
誰能解釋兩者的復雜性?
遞歸解決方案的復雜度為O(n!)
因為它由以下方程控制: T(n) = n * T(n-1) + O(1)
。
迭代解決方案具有三個嵌套循環,因此具有O(n^3)
的復雜性。
但是,迭代解決方案不會為除3
之外的任何數字生成正確的排列。
對於n = 3
,您可以看到n * (n - 1) * (n-2) = n!
. LHS 是O(n^3)
(或者更確切地說是O(n^n)
因為這里n=3
),RHS 是O(n!)
。
對於列表大小的較大值,例如n
,您可以有n
嵌套循環,這將提供有效的排列。 在這種情況下,復雜性將是O(n^n)
,這比O(n!)
大得多,或者更確切地說,是n! < n^n
n! < n^n
。 有一個相當不錯的關系稱為斯特林近似,它解釋了這種關系。
在這個問題中,輸出(這是巨大的)很重要,而不是例程的實現。 對於n
不同的項目,有n!
排列作為答案返回,因此我們至少有O(n!)
復雜度。
借助斯特林近似
O(n!) = O(n^(1/2+n)/exp(n)) = O(sqrt(n) * (n/e)^n)
我們可以很容易地看到,對於任何常量c
, O(n!) > O(n^c)
,這就是為什么實現本身添加另一個O(n^3)
並不重要,因為
O(n!) + O(n^3) = O(n!)
就調用makePermutations
方法的次數而言,確切的時間復雜度為:
O( 1 + n + n(n-1) + n(n-1)(n-2) + ... )
對於 n = 3:
O( 1 + 3 + (3*2) + (3*2*1) ) = O(16)
這意味着,對於 n = 3,方法makePermutations
將被調用 16 次。
我認為最佳排列 function 的空間復雜度為 O(n * n,),因為有 n。 返回的總數為 arrays,其中每個 arrays 的大小為 n。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.