[英]What is the time complexity of an iteration through all possible sequences of an array
一種算法,遍歷數組中所有可能的索引序列。
單個循環的時間復雜度是線性的,兩個嵌套循環是二次O(n ^ 2)。 但是,如果另一個循環嵌套並通過這兩個索引之間分隔的所有索引怎么辦? 時間復雜度是否升至立方O(n ^ 3)? 當N變得非常大時,似乎沒有足夠的迭代來考慮復雜性立方體,但似乎很大的是二次O(n ^ 2)
這是考慮N =數組長度的算法
for(int i=0; i < N; i++)
{
for(int j=i; j < N; j++)
{
for(int start=i; start <= j; start++)
{
//statement
}
}
}
這是N = 7時迭代的簡單視覺(直到i = 7):
等等..
我們是否應該將時間復雜度視為二次,三次或不同的尺寸復雜度?
對於基本的
for (int i = 0; i < N; i++) {
for (int j = i; j < N; j++) {
// something
}
}
我們執行something
n * (n+1) / 2
倍=> O(n^2)
至於原因:它是簡化形式
sum (sum 1 from y=x to n) from x=1 to n
。
對於您的新案例,我們有一個類似的公式:
sum (sum (sum 1 from z=x to y) from y=x to n) from x=1 to n
。 結果是n * (n + 1) * (n + 2) / 6
=> O(n^3)
=>時間復雜度是立方的 。
兩個公式中的1
是您輸入something
的成本的地方。 特別是在進一步擴展公式的地方。
請注意,所有指數可能會被一個關閉,我沒有特別注意<
vs <=
等。
簡答案, O(choose(N+k, N))
與O(choose(N+k, k))
相同O(choose(N+k, k))
。
這是如何到達那里的長期答案。
您的基本問題版本正確。 使用k
嵌套循環,當N
變為無窮大時,您的復雜性將為O(N^k)
。 然而,由於k
和N
都變化,行為更復雜。
讓我們考慮相反的極端。 假設N
是固定的,並且k
變化。 如果N
為0,則你的時間是恆定的,因為最外層的循環在第一次迭代時失敗。如果N = 1
那么你的時間是O(k)
因為你只需要一個選擇就可以完成所有嵌套級別而且只有一個每次選擇。 如果N = 2
則會發生更有趣的事情,你會一遍又一遍地進行嵌套,需要時間O(k^N)
。 並且通常,對於固定的N
,時間是O(k^N)
,其中k
一個因子是由於遍歷嵌套所花費的時間,並且O(k^(N-1))
取決於序列前進的位置。 這是意想不到的對稱性!
現在如果k
和N
都很大會發生什么? 這是什么時間復雜度? 那么這里是給你直覺的東西。
我們可以描述我們到達最里面循環的所有時間嗎? 是! 考慮k+N-1
個時隙,其中k
為“進入另一個循環” ,其中N-1
為“我們將索引提前1”。 我斷言如下:
1 < N
我們實際上還需要一個在獨特工作中才能達到目的。 現在這看起來像一團糟,但有一個技巧可以非常意外地簡化它。
訣竅是這個。 假設我們采用了其中一種模式,並在最后一段“最后輸入一個循環”條目的某個地方插入了一個額外的“我們將索引提前1” 。 有多少種方法可以做到這一點? 答案是我們可以在最后一段中的任意兩個點之間插入最后一個條目,包括開頭和結尾,並且還有一種方法可以比條目更多。 換句話說,執行此操作的方式的數量與此迭代的獨特工作量相匹配!
這意味着總工作與O(choose(N+k, N))
成正比, O(choose(N+k, N))
也是O(choose(N+k, k))
。
值得知道的是,從二項式公式的正態近似,如果N = k
則結果為O(2^(N+k)/sqrt(N+k))
,其確實比多項式增長得快。 如果您需要更一般或更精確的近似,可以使用Stirling的近似值來choose(N+k, N) = (N+k)! / ( N! k! )
choose(N+k, N) = (N+k)! / ( N! k! )
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.