簡體   English   中英

排列的時間復雜度 function

[英]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)

我們可以很容易地看到,對於任何常量cO(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM