第一次嘗試
既然你是印刷每個排列的n
-string的和有這樣n!
串,時間複雜度出現O(n!)
。
復發,可以形象地顯示(不完整,但你應該明白我的意思),如下所示:
-------------- p("", "ABC")------------
/ | \
p("A", "BC") p("B", "AC") p("C", "AB")
| |
p("AB", "C") p("AC", "B")
| |
p("ABC", "") p("ACB", "")
正如你所看到的,調用樹的葉子具有所需的排列的形式prefix
您打印在基本情況下。由於此樹中的樹葉數量爲n!
,因此複雜度爲出現O(n!)
。
爲什麼它不是(低至)O(nlogn)
的直觀推理是O(nlogn)
的其他重複看起來不像這樣。例如,在合併排序的情況下,您將問題大小減半並在每個步驟中執行線性合併操作。由於有log(n)
步驟,因此您得到O(nlog(n))
作爲重複的解決方案。然而,在這個問題中,由於你必須做更多的工作,所以時間複雜度更高。
更新在首次嘗試分析評論
後上面是不完全正確。這裏還有更多。確實呼叫樹有n!
樹葉。但爲了達到這些葉子,我們必須在代表遞歸調用的每個非葉節點上做更多的工作。對於具有n
字符的字符串str
,第一級中的節點數顯然爲n
。在進行下一次遞歸調用之前,還會進行字符串連接。這些使得它更耗時。每個n
呼叫最終會附加總共至少n
個字符。
在第二級,這些n
節點中的每一個節點都會產生(n-1)
節點,總共得到n(n-1)
。同樣,有很多字符串連接。
這個過程會一直繼續,直到遞歸調出n!
樹葉爲止。在調用樹節點的總數是
= n + n(n-1) + n(n-1)(n-2) + ... + n(n-1)(n-2)...1
= n(n-1)(n-2)...1 + n(n-1)(n-2)...2 + n(n-1)(n-2)...3 + ... + n(n-1) + n
= n! + (n!/2) + (n!/(2.3)) + ... + (n!/(1.2.3...(n-1)) --- these are n terms
= n! (1 + 1/2 + 1/2.3 + 1/2.3.4 + ...)
= n! (1.71828...)
= O(n!)
在每種這些調用的,至少有n
字符被附加(以及如保羅指出,正在打印一個新的生產線),總量工作是O(n.n!)
。
有(N + 1)!字符輸出,和(n + 1)!不是O(n!)所以這個答案是不對的。 –
@PaulHankin如果'n = length(「str」)',我認爲它們不是'(n + 1)!',而是'n.n!'(18 = 3.3!)個字符。但我同意,調用'permutation'的次數多於'O(n!)'。 –
每行有(n + 1)個字符:n個數字和一個回車符。所以(n + 1)!總。 –