在解題或競程時,通常都會有一些時間或記憶體的限制
若超出限制,就可能會出現 TLE(Time Limit Exceed)或 MLE(Memory Limit Exceed)的錯誤
為了能夠讓程式順利執行,處理時間複雜度和空間複雜度的部分就格外重要


時間複雜度 (Time Complexity) Link to heading

簡單來說,就是電腦在執行這段演算法時所需的計算量
但不同的電腦因為硬體或其他因素,在實際執行演算法時所花費的時間還是不同,因此時間複雜度並不代表實際所花費的時間

空間複雜度 (Space Complexity) Link to heading

電腦在執行這段演算法時所需的最大記憶體使用量


Big O Notation (大 O 符號) Link to heading

一般我們會用 Big O Notation (簡稱 big O) 來表示時間與空間複雜度
例如給定一個 array 的輸入資料,當這個演算法需要遍歷整個 array 一遍才能完成計算,我們就可以用 O(n) 來表示這個演算法的時間複雜度,n 代表這個輸入資料 array 的長度

for i in array:
    print(i)

若今天是兩個 for loop 的巢狀結構來遍歷 array:

for i in array:
    for j in array:
        current = i + j
        print(current)

此時的時間複雜度就可以寫成 O(n²)

若今天的計算量是成 對數成長,譬如經典的二分搜尋法 (binary search)

def binary_search(array: List[int], target: int):
    left = 0
    right = len(array) - 1
    
    while (left <= right):
        mid = (left + right) // 2;
        if array[mid] == target:
            return mid
        elif array[mid] < target
            left = mid + 1;
        else{
            right = mid - 1;
        
    return -1;

此時的時間複雜度就可以寫成 O(log n)


空間複雜度也與時間複雜度算方式類似,若今天給定一個輸入資料 array,在演算法的執行過程中,須建立一個長度相同的 new_array 才能完成計算,則一樣可用 O(n) 來表示這個演算法的空間複雜度

new_array = []
for i in array:
    new_array.append(i)

若是兩個 for loop 的巢狀結構,則可以表示為 O(n²)

new_array = []
for i in array:
    for j in array:
        current = i + j
        new_array.append(current)

解題 Link to heading

在解題時,以 Leetcode 為例,通常題目都會給我們一些條件限制,也就是 Constraints 的部分,我們就可以透過 Constraints 來簡單判斷這題可接受的最大時間與空間複雜度是多少,進而來思考我們能用的演算法有哪些
以下就用表格稍微歸納了在不同的時間與空間複雜度之下,我們能用哪些演算法來解題~


Time Complexity : 操作步驟次數約小於 10^7 次 Link to heading

輸入大小 n可接受的最大時間複雜度範例演算法
≤ 10O(n!)、O(2^n)暴力列舉、DFS、排列組合
≤ 100O(n³)三層迴圈、DP with 3D state
≤ 1,000O(n²)雙層迴圈、Floyd-Warshall、窮舉配對
≤ 10⁴O(n log n)排序、堆、貪心、分治
≤ 10⁵O(n log n)Hash、Union-Find、線段樹
≤ 10⁶O(n)一次遍歷、prefix sum、bucket sort
≤ 10⁷O(n) (極限)Bitwise 處理、rolling hash 等

Space Complexity : 約小於 10^6 Link to heading

空間複雜度安全上限(元素數量)範例資料結構
O(1)任意原地操作(in-place)、指標
O(n)n ≤ 10⁶list, set, dict, DSU, prefix sum
O(n log n)n ≈ 10⁵排序輔助陣列、線段樹
O(n²)n ≤ 10³矩陣、鄰接矩陣、DP 二維狀態表
O(2^n)n ≤ 20Bitmask DP、狀態記憶


參考來源: Link to heading

  1. 我的小腦袋
  2. ChatGPT