[演算法] Big O Notation, Time Complexity & Space Complexity
TL;DR;
好的程式碼通常是指好的「閱讀性/維護性(readable/maintainable)」和「可擴展性(scalable)」,而可擴展性又可以分成時間複雜度(速度)和空間複雜度(space complexity)。其中時間複雜度就可以使用 Big O Notation 來衡量,也就是用來衡量當資料量持續 增加時,程式執行的時間增加的比率為何。
O(1)
:沒有迴圈O(log N)
:通常會是搜尋使用的演算法,會排序後先對半分O(n)
:一層迴圈O(n*log(n))
:通常是排序的操作O(n^2)
:兩層迴圈(迴圈內有迴圈)O(2^N)
:recursiveO(n!)
:每個元素都在跑一次回圈
Big O Notation & Time Complexity
同樣的問題可以用許多種不同的方式加以解決,因此,我們需要一些指標來評量各種方式的好壞。在演算法中,常會使用 Big O Notation
和 Time Complexity
來衡量一個演算法(函式)的好壞。通常,會根據這個函式隨著輸入的資料量增加時,執行時間會拉長多少來作為衡量的標準之一。
資訊
Big O Notation 代表演算法時間函式的上限(Upper bound),表示在「最壞的狀況」下,演算法的執行時間不會超過 Big-Ο。--- 演算法評估與資料型別
常見的時間複雜度(Time Complexity)
常見的時間複雜度由快到慢排列包含:
- 優良
O(1)
O(log n)
O(n)
- 可接受
O(n log n)
- 差
O(n ^ 2)
O(2 ^ n)
O*(n!)
💡 在演算法中,
log n
的慣例指的是以 2 為底的意思,也就是 2 的幾次方。
Constant Run Time (O(1)
)
第一個類型是屬於 constant run time(O(1)
),這個演算法(函式)的執行時間不會隨著輸入資料量的增加而增加。
以下面的函式為例,不論我們代入的資料量有多大,它都只是輸出陣列中第一和第二個元素的值,因此執行時間不會隨著輸入資料量的增加而增加。
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/**
* Constant Run Time:不會隨著輸入的資料量越大而使得執行時間變長
* Big O Notation: "O(1)"
**/
function log(arr) {
console.log(arr[0]);
console.log(arr[1]);
}
log(arr1); // 1, 2
log(arr2); // 1, 2