時間複雜度O(n)和空間複雜度

wade3po發表於2019-03-27

演算法對於敲程式碼的應該都聽過,不管是複雜的還是簡單的,衡量演算法效率的兩個重要指標就是時間複雜度和空間複雜度。

時間複雜度:評估執行程式所需的時間。可以估算出程式對處理器的使用程度。空間複雜度:評估執行程式所需的儲存空間。可以估算出程式對計算機記憶體的使用程度。

空間複雜度:對一個演算法在執行過程中臨時佔用儲存空間大小的量度。查了很多,對於計算空間複雜度還是沒有一個很好的理解,因為有些說需要把演算法內部使用的全域性變數算在內,有些說只需要把演算法內部變數算在內,有些說需要迴圈幾次,每一次的臨時變數需要疊加算,有些又說臨時變數會被銷燬,還是隻算一個。所以我們只要記住,空間複雜度就是這個演算法執行過程中臨時佔用的記憶體。

時間複雜度:你可以簡單理解演算法執行所需要的時間,我們一般會以犧牲空間複雜度來實現時間複雜度最優。如果單純以時間來衡量時間複雜度不是很準確,因為相同演算法在不同環境或者不同資料下執行時間是不一樣的。所以,時間複雜度一般用大O符號表示法。

大O表示法有三個規則:

1.用常數1取代執行時間中的所有加法常數

2.只保留最高階項

3.去除最高階的常數

常數階:

var a = 1;//執行1次

var b = 2;//執行1次

console.log(a  +  b);//執行1次
複製程式碼

比如這樣的程式碼,每一句都是執行一次,加起來是三次,套用規則1,這段程式碼時間複雜度為O(1)。

線性階:

var a = 1;//執行1次

for(var i = 0; i < n;i++){ 

   console.log(i)//執行n次

}
複製程式碼

總共執行了n+1次,套用規則,保留高階項,去除高階常數,所以時間複雜度是O(n)。

對數階:

var a = 1;//執行1次

while (a < n){ 

   a *= 2; //執行了logn次

}
複製程式碼

這段程式碼while裡面要判斷執行次數,假設執行次數是x那麼要成立2^x > n,所以得出來的執行次數就是logn(這是基本的數學了,不懂的話我也無能為力)。應該有人會覺得log的底數是10,而我們這邊底數是2,但在演算法裡面,我們只會用數學的方法把n無限大去比較,所以不管底數是多少,演算法的時間複雜度的增長與處理資料多少的增長的關係是一樣的。套用規則,這段程式碼執行次數logn + 1,保留高階項,去除高階常數,所以時間複雜度是O(logn)。

平方階:

for (var i = 0; i < n; i++) { 

// 語句執行n次    

for (var j = 0; j < m; j++) { 語句執行m次

        console.log(i + j); // 語句執行n*m次   

 }}
複製程式碼

同樣的,這邊執行次數是n*m,用數學的方式n和m趨於無窮大的時候,n≈m,於是執行次數就是n^2,所以時間複雜度是O(n^2)。當然還有n的三次方、四次方等。

演算法還有很多很多的時間複雜度,你要是數學學得好,你就可以找出更多的時間複雜度,本人要是高中時候還能多找幾個,現在只能理解這幾個了。

而時間複雜度也是能比較的,單以這幾個而言:

O(1)<O(logn)<O(n)<O(n²)<O(n³)

一個演算法執行所消耗的時間理論上是不能算出來的,我們可以在程式中測試獲得。我們不可能也沒必要對每個演算法進行測試,我們通過類似上面的方法,就能大概的比較出演算法的執行效率。

分享時間複雜度這個概念只是想讓大家瞭解一下我們寫的一些程式碼執行效率是可以比較的,時間複雜度也並不能單純的以上面單個來看,經常會組合夾雜著出現。

Coding 個人筆記

時間複雜度O(n)和空間複雜度

相關文章