循序漸進帶你學習時間複雜度和空間複雜度。 - rocky0429 -
時間複雜度:
下面我們來看乙個簡單的求和的函式:
def get_sum(n):
sum = 0
for i in range(1,n+1):
sum += i
return sum
print(get_sum(10))
我們仔細去分析一下上述**,其實可以發現統計執行求和的賦值語句的次數可能是乙個好的基本計數單位,在上面 get_sum 函式中,賦值語句的數量是 1 (sum = 0)加上 n (執行 sum += i 的次數)。
我們一般用乙個叫 t 的函式來表示賦值語句的總數量,比如上面的例子可以表示成 t(n) = n + 1。這裡的 n 一般指的是「資料的規模大小」,所以前面的等式可以理解為「解決乙個規模大小為 n,對應 n+1 步操作步數的問題,所需的時間為 t(n)」。
對於 n 來說,它可以取 10,100,1000 或者其它更大的數,我們都知道求解大規模的問題所需的時間比求解小規模要多一些,那麼我們接下來的目標就很明確了,那就是「尋找程式的執行時間是如何隨著問題規模的變化而變化」。
我們的科學家前輩們又對這種分析方法進行了更為深遠的思考,他們發現有限的操作次數對於 t(n) 的影響,並不如某些佔據主要地位的操作部分重要,換句話說就是「當資料的規模越來越大時,t(n) 函式中的某一部分掩蓋了其它部分對函式的影響」。最終,這個起主導作用的部分用來對函式進行比較,所以接下來就是我們所熟知的大 o閃亮登場的時間了。
【數量級】函式用來描述當規模 n 增加時,t(n) 函式中增長最快的部分,這個數量級函式我們一般用「大 o」表示,記做 o(f(n))。它提供了計算過程中實際步數的近似值,函式 f(n) 是原始函式 t(n) 中主導部分的簡化表示。
在上面的求和函式的那個例子中,t(n) = n + 1,當 n 增大時,常數 1 對於最後的結果來說越來不越沒存在感,如果我們需要 t(n) 的近似值的話,我們要做的就是把 1 給忽略掉,直接認為 t(n) 的執行時間就是 o(n)。這裡你一定要搞明白,這裡不是說 1 對 t(n) 不重要,而是當 n 增到很大時,丟掉 1 所得到的近似值同樣很精確。
再舉個例子,比如有乙個演算法的 t(n) = 2n^2+ 2n + 1000,當 n 為 10 或者 20 的時候,常數 1000 看起來對 t(n) 起著決定性的作用。但是當 n 為 1000 或者 10000 或者更大呢?n^2 起到了主要的作用。實際上,當 n 非常大時,後面兩項對於最終的結果來說已經是無足輕重了。與上面求和函式的例子很相似,當 n 越來越大的時候,我們就可以忽略其它項,只關注用 2n^2 來代表 t(n) 的近似值。同樣的是,係數 2 的作用也會隨著 n 的增大,作用變得越來越小,從而也可以忽略。我們這時候就會說 t(n) 的數量級 f(n) = n^2,即 o(n^2)。
儘管前面的兩個例子中沒有體現,但是我們還是應該注意到有時候演算法的執行時間還取決於「具體資料」而不僅僅是「問題的規模大小」。對於這樣的演算法,我們把它們的執**況分為「最優情況」、「最壞情況」和「平均情況」。
某個特定的資料集能讓演算法的執**況極好,這就是最「最好情況」,而另乙個不同的資料會讓演算法的執**況變得極差,這就是「最壞情況」。不過在大多數情況下,演算法的執**況都介於這兩種極端情況之間,也就是「平均情況」。因此一定要理解好不同情況之間的差別,不要被極端情況給帶了節奏。
對於「最優情況」,沒有什麼大的價值,因為它沒有提供什麼有用資訊,反應的只是最樂觀最理想的情況,沒有參考價值。「平均情況」是對演算法的乙個全面評價,因為它完整全面的反映了這個演算法的性質,但從另一方面來說,這種衡量並沒有什麼保證,並不是每個運算都能在這種情況內完成。而對於「最壞情況」,它提供了一種保證,這個保證執行時間將不會再壞了,**所以一般我們所算的時間複雜度是最壞情況下的時間複雜度**,這和我們平時做事要考慮到最壞的情況是乙個道理。在上圖中,我們可以看到當 n 很小時,函式之間不易區分,很難說誰處於主導地位,但是當 n 增大時,我們就能看到很明顯的區別,誰是老大一目了然:
o(1) < o(logn) < o(n) < o(nlogn) < o(n^2) < o(n^3) < o(2^n)
演算法複雜度 時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...
演算法複雜度 時間複雜度和空間複雜度
演算法複雜度 時間複雜度和空間複雜度 關鍵字 演算法複雜度 時間複雜度 空間複雜度 1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時 間多,哪個演算法花費的時間少就可以...
演算法複雜度 時間複雜度和空間複雜度
演算法的時間複雜度是指執行演算法所需要的計算工作量。n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 存在乙個正...