關於時間複雜度空間複雜度的理解

2022-09-03 02:12:12 字數 1395 閱讀 2048

對於非科班出身的人來說,在學習演算法的時候經常會遇到的問題就是關於對事件空間複雜度的 理解。

「大 o 表示法」的準確的數學描述方式非常枯燥,我在這裡就不貼出來湊字數了,其實大 o 表示法的意思挺簡單的,就是表示:隨著輸入的值變化,程式執行所需要的時間與輸入值的變化關係。

我們先看第乙個**,這是乙個函式,輸入乙個陣列,輸出這個陣列裡元數的和。

int count(int a, int n) 

return result;

}這裡的時間複雜度是o(n),即隨著n的增長,o(n)也隨之線性增長,我們用o(n)來表示這種線性時間複雜度

接下來我們來看第二行**

int binary_search(int a, int key, int imin, int imax)

else

}

對於這個程式來說,如果它處理 n 個元素求和所花的時間是 t,那麼它處理 n 2 個元素的和所花的時間是多少呢?是 t 2 嗎?

如果頭腦算不清楚,我們可以拿實際的數字來實驗,二分查詢每次(幾乎)可以去掉一半的候選數字。所以假如 n = 1024,那麼它最多要找多少次呢?答案是 10 次,因為 2^10 = 1024,每次去掉一半,10 次之後就只剩下唯一乙個元素了。

好,這個時候,如果元素的個數翻一倍,變成 2048 個,那麼它最多要找多少次呢?相信大家都能算出來吧?答案是 11 次,因為 2 ^ 11 = 2048。

所以在這個例子中,輸入的元素個數雖然翻倍,但是程式執行所花的時間卻只增加了 1,我們把這種時間複雜度要叫「對數」時間複雜度,用 o(logn) 來表示。

除了剛剛講的「線性」時間複雜度和「對數」時間複雜度。我們還有以下這次常見的時間復度數。

「常數」時間複雜度,例如返回乙個有序陣列中的最小數,這個數因為始終在第乙個位置,所以就不會受到陣列大小的影響,無論陣列多大,我們都可以在乙個固定的時間返回結果。

「線性對數」時間複雜度,即 o(n*logn),這個複雜度比較常見,因為常見的高效的排序演算法,都是這個時間複雜度,比如快速排序,堆排序,歸併排序等。

之前我很多次在網上看到說把1000萬次運算當做實際的1s來運算。我的計算機主頻是2.5ghz,所以每秒可以執行25億次彙編指令,加入每次迴圈裡面的**可以產生250條彙編指令,才能夠得到1s1千萬次迴圈的結果,不是很確定,有機會可以yongxcode試一下

總結一下學習時間複雜度的知識對於我們的工作有什麼用:

對於不同的資料規模,能夠決策採用不同的解決方案。

了解什麼情況下用暴力解法就能夠解決問題,避免寫複雜的**。

在寫**之前,就能夠預估程式的執行時間,從而可以知道是否能夠滿足產品需求。

在程式出現效能瓶頸時,能夠有解決方案而不是抓瞎。

參考

時間複雜度 空間複雜度

時間複雜度 在電腦科學中,演算法的時間複雜度是乙個函式,它定性描述了該演算法的執行時間。這是乙個關於代表演算法輸入值的字串 的長度的函式。時間複雜度常用大o符號 表述,不包括這個函式的低階項和首項係數。計算時間複雜度的方法 1 只保留高階項,低階項直接丟棄 2 係數不要 3 執行次數是常數是為o 1...

時間複雜度 空間複雜度

演算法複雜度分為時間複雜度和空間複雜度。其作用 時間複雜度是指執行演算法所需要的計算工作量 而空間複雜度是指執行這個演算法所需要的記憶體空間。一 時間複雜度 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道...

時間複雜度 空間複雜度

一 時間複雜度 實際是指程式執行次數,而不是程式執行時間 1.我們一般討論的是最壞時間複雜度,這樣做的原因是 最壞情況下的時間複雜度是演算法在任何輸入例項上執行時間的上限,以最壞代表最全。2.時間複雜度的書寫規則 忽略常數項,用o 1 表示 選取最壞時間複雜度即選取增長最快的項 遞迴的時間複雜度 遞...