算法評估標準:時間複雜度與空間複雜度

1 概念

最近開始看看leetcode,發現自己對時間複雜度和空間複雜度沒有一個清晰地認識。就去看了看程序員小灰寫的算法之旅。這裏寫篇博客記錄一下這部分的知識方便以後查閱。


先說說什麼是算法:
在計算機領域裏,算法是一系列程序指令,用於處理特定 的運算和邏輯問題。 衡量算法優劣的主要標準是時間複雜度和空間複雜度。


而是什麼是時間複雜度和空間複雜度呢?
**時間複雜度:時間複雜度是對一個算法運行時間長短的量度。**用大O表 示,記作T(n)=O(f(n))。
常見的時間複雜度按照從低到高的順序,包括O(1)、 O(logn)、O(n)、O(nlogn)、O(n2)等。


**空間複雜度:**空間複雜度是對一個算法在運行過程中臨時佔用存儲空間 大小的量度用大O表示,記作S(n)=O(f(n))。
常見的空間複雜度按照從低到高的順序,包括O(1)、 O(n)、O(n2)等。其中遞歸算法的空間複雜度和遞歸深度成正 比。

2 時間複雜度

可以對抽象出計算的時間公式,然後對公式使用一下規則

  • 如果運行時間是常數量級,則用常數1表示
  • 只保留時間函數中的最高階項
  • 如果最高階項存在,則省去最高階項前面的係數



T(n) = 2,只有常數量級,時間複雜度爲:T(n) =O(1)。
T(n)= 3n,最高階項爲3n,省去係數3,時間複雜度爲:T(n)=O(n)。
T(n) = 5logn, 最高階項爲logn, 時間複雜度爲:T(n)=O(logn)
T(n) = 5*n^3+ 3n 最高階項爲3n 省去係數5 時間複雜度是O(n^3)


時間複雜度的是對真正的時間複雜度的一種漸進(大 O 時間複雜度實際上並不具體表示代碼真正的執行時間,而是表示代碼執行時間隨數據規模增長的變化趨勢),模擬的是n趨於無窮大時的複雜度。所以纔有上面的計算規則,應因爲在n趨近於無窮大時,其他因素都可以忽略。

幾種常見時間複雜度:
常數時間複雜度:如果對於一個算法,T(n)的上界與輸入大小無關,則稱其具有常數時間,記作O(1),如訪問數組內的單個元素,散列表等。
線性時間複雜度:如果需求是找到無序數組中的最小元素,因爲需要遍歷所有元素來找到最小值,是一個線性時間操作,記作O(n)
對數時間複雜度:計算機採用二進制計數,所以對數一般以2爲底。由於不同的對數公式只有底數不同,而且都是常數,所以O計法中將這個底數拋棄,記爲O(logn),常見的有二叉樹相關操作和二分搜索。對數時間中每增加一個輸入,所需額外計算時間變小。
指數時間複雜度:一個問題求解所需要的計算時間n隨着n的增加呈指數型增長
以上幾種時間複雜度, 當n的取值足夠大時,不難得出下面的結論
O(1)<O(logn)<O(n)<O(n2)

3 空間複雜度

存儲算法本身所佔的存儲空間
算法的輸入輸出數據所佔用的存儲空間
算法在運行過程中臨時佔用的存儲空間


基於以上規則也可以總計出來幾種常見的空間複雜度
1. 常量空間。當算法的存儲空間大小固定,和輸入規模沒有直接的關係時,空間複雜度記作O(1)。
2 線性空間。當算法分配的空間是一個線性的集合(如數組),並且集合大小和輸入規模n成正比時O(n)
3 二維空間。當算法分配的空間是一個二維數組集合,並且集合的長度和寬度都與輸入規模n成正比時,空間複雜度記作O(n2)
4 遞歸空間 執行遞歸操作所需要的內存空間和遞歸的深度成正比。純粹的遞歸操作的空間複雜度也是線性的,如果遞歸的深度是n,那麼空間複雜度就是O(n)。


總體而言,一個算法的空間複雜度只考慮運行過程中爲局部變量分配的存儲空間的大小,包括:

  • 參數表中形參變量分配的存儲空間
  • 函數體中定義的局部變量分配的存儲空間
  • 如果一個算法是遞歸的,那麼空間複雜度是遞歸所使用的堆棧空間大小,

4 參考鏈接

漫畫算法:小灰的算法之旅
https://zhuanlan.zhihu.com/p/118425860

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章