1. 時間複雜度和空間複雜度 (7 天掌握演算法面試必考知識點)

zailushang發表於2020-06-28

學習計劃

由於每天都需要寫學習心得和作業,所以寫此貼作為筆記。也希望可以幫助到有需要的同學。

1、時間複雜度

(1)時間複雜度的統計維度

  • O(1): Constant Complexity 常數複雜度
  • O(log n): Logarithmic Complexity 對數複雜度
  • O(n): Linear Complexity 線性時間複雜度
  • O(n2): N Square Complexity 平方
  • O(n3): N CubicComplexity 立方
  • O(2n): Exponential Growth 指數
  • O(n!): Factorial 階乘

(2)各時間複雜度的耗時曲線


從圖中可以看出,當n小於5時,不同的時間複雜度耗時差不多。
當n增大時,不同時間複雜度演算法耗時差距非常大。所以也就不難理解,大型公司對演算法的要求越來越高,是因為當遇到大資料量處理時,不同的演算法能力,需要的伺服器成本和程式碼效能是有天壤之別的。

(3)演算法面試題的四個套件

  • 演算法題的內容確認無誤;
  • 思考所有可能解決的辦法;
  • 比較這些方法的時間和空間複雜度;
  • 找出最優的解決方案(時間複雜度最低,兼顧內容使用更少的)

(4)遞迴的時間複雜度分析

  • 將遞迴的執行順序畫出樹形結構,稱為遞迴狀態的遞迴樹;
  • 主定理計算時間複雜度

比如:斐波那契數列
Fib: 1, 1, 2, 3, 5, 8, 13, 21, 34...
方法定義:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)

def fib(n: int):
if n < 2: return n
return fib(n-1) + fib(n-2)

繪製遞迴圖,以n=6為例:

常用演算法應用主定理:(記住如下演算法對應公式,並嘗試理解)

2、空間複雜度

空間複雜度和時間複雜度的情況類似,但是更加簡單。

陣列的長度

如果程式碼中開了陣列,則陣列的長度基本就是空間複雜度。
比如:

  • 一維陣列,陣列長度等於元素個數,則空間複雜度就是O(n)
  • 二維陣列,陣列長度為n2,則空間複雜度為O(n2)

遞迴深度

如果程式碼中有遞迴,那麼遞迴最大深度,就是空間複雜度的最大值。如果遞迴裡面又開了陣列,那麼兩者中的最大值就是空間複雜度。

實戰分析

詳見leetcode的爬樓梯示例:爬樓梯題解

3、小結

  • 常用工具配置
  • 基本功和程式設計指法
  • 常見的時間、空間複雜度分析 對於開發來說,掌握熟悉的工具和TOP用法,能節省開發中的工具使用效率。 對於頂級工程師來說,對自己程式碼的時間複雜度和空間複雜度瞭解,是必備技能。

總結

時間複雜度:假設入參為n,程式執行的次數與n的關係,即為時間複雜度。
時間複雜度優化順序:O(1) > O(log n) > O(n) > O(n2) > O(n3) > O(2n) > O(n!)

空間複雜度:程式碼中陣列的大小或遞迴深度的最大值。
空間複雜度優化順序:O(1) > O(log n) > O(n) > O(n2) > O(n3) > O(2n) > O(n!)

為什麼複雜度對於程式碼來說如此重要?
從網際網路公司成本來看:

  • 硬體成本:時間複雜度低的程式碼,可以降低CPU壓力,減少伺服器的CPU成本;空間複雜度低的程式碼,可以降低記憶體佔用,減少伺服器的記憶體成本;
  • 產品成本:時間複雜度和空間複雜度越低,程式執行時間越低和遇到的效能故障越少,產品的效能就會越好,越容易獲取使用者喜歡。
  • 質量評估成本:對設計的演算法效能有兩種評測方法,一是執行耗時評估,成本高、不穩定、強依賴硬體,而就是時間複雜度和空間複雜度評估,成本低、準確性高。

參考資料:

相關文章