數據結構與算法 —— 常用時間複雜度與空間複雜度


參考文章:
https://juejin.im/entry/5b38f3b6e51d4558de5c0139
https://blog.csdn.net/zolalad/article/details/11848739

常用數據結構和算法時間複雜度速查表

速查表官網
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

時間複雜度

常見的算法時間複雜度由小到大依次爲:

Ο(1)<Ο(logn)<Ο(n)<Ο(nlogn)<Ο(n2)<Ο(n3)<…<Ο(2^n)<Ο(n!)

在這裏插入圖片描述

Ο(1)

表示基本語句的執行次數是一個常數,一般來說,只要算法中不存在循環語句,其時間複雜度就是Ο(1)

其中Ο(logn)、Ο(n)、 Ο(nlogn)、Ο(n2)和Ο(n3)稱爲多項式時間,計算機科學家普遍認爲(即多項式時間複雜度的算法)是有效算法,

Ο(logn)

如果循環中有二分則爲O(logn), 再一個例子:對半查找,叫做二分

for (int i = 0; i < n; i = i*2)
{
    cout<<"d";
}

int i = 1;
while (i < n)
{
    i = i*2;
}

O(N)

最基礎的循環執行n次

for (int i = 0; i < n; i++)
{   
    cout<< "d";
}

O(nlogN)

就是O(logn)代碼循環N遍 也就是兩重循環,一重循環爲n,第二重循環爲logN

for (int i = 0; i < n; i++)
{   
    //二分查找,或者O(logN)的算法
    while (i < n)
    {
        i = i*2;
    }
}

O(n^2) O(n³)

雙重O(n)嵌套
O(n³)相當於三層n循環,其它的類似。N的K次方就是n的K次循環
後面比如Ο(2^n) , Ο(n!)的時間複雜度太高,一般就不考慮使用了。
一個經驗規則:其中c是一個常量,如果一個算法的複雜度爲Ο(1)<Ο(logn)<Ο(n)<Ο(nlogn),那麼這個算法時間效率比較高Ο(n2)<Ο(n3)幾個則差強人意。,如果是2n ,3n ,n!,則不要考慮了。

如何計算時間複雜度

可以假設n爲5,看代碼執行幾行,然後假設n爲10看代碼執行幾行。由此得到時間複雜度。

舉例:計算1+2+3….n

第一種:for(int I = 1;I <= n;i++){ sum+=I;} 他的時間複雜度爲代碼執行N次,爲O(n)
第二種:求和公式n*(n+1)/2 則O(1)

舉例:斐波那契數列。1,1,2,3,5,8,13… F(n) = F(n-1) + F(n-2)

第一種:遞歸程序,def fib(n) { if(n ==1) return 1; return fib(n-1) + fib(n-2) }
遞歸時,時間複雜度: N =1執行1行, n=2執行3行 n=3執行4行 n=4執行8
N = 5執行13
類似於2的N次方的複雜度 空間複雜度爲S(1)
第二種方法:動態規劃使用臨時變量移動O(N) S(1)

    int fib(int n) {
        if (n < 2) {
            return n;
        }
        int a = 0;
        int b = 1;
        int sum = 0;
        for (int i = 2; i <= n; i++) {
            sum = (a + b) % 1000000007;
            a = b;
            b = sum;
        }
        return sum;
    }

一般我們討論的時間複雜度都是最壞時間複雜度

我們可以看到冒泡,交換,選擇,插入時間複雜度一樣爲n2所以他們的性能差不多
而基數,希爾,快速,歸併,堆排序,時間複雜度爲nlogn速度就要要快一些

空間複雜度

空間複雜度(Space Complexity)是對一個算法在運行過程中臨時佔用存儲空間大小的量度
我們用 S(n) 來定義。
空間複雜度比較常用的有:O(1)、O(n)、O(n²)

我們在寫代碼時,完全可以用空間來換取時間,比如說,要判斷某某年是不是閏年,你可能會花一點心思寫了一個算法,而且由於是一個算法,也就意味着,每次給一個年份,都是要通過計算得到是否是閏年的結果。還有另一個辦法就是,事先建立一個有2 050個元素的數組(年數略比現實多一點),然後把所有的年份按下標的數字對應,如果是閏年,此數組項的值就是1,如果不是值爲0。
可表示爲 O(1)
舉例:

    int i = 1;
    int j = 2;
    ++i;
    j++;
    int m = i + j;

代碼中的 i、j、m 所分配的空間都不隨着處理數據量變化,因此它的空間複雜度 S(n) = O(1)
O(1)是說數據規模和臨時變量數目無關,並不是說僅僅定義一個臨時變量。舉例:無論數據規模多大,我都定義100個變量,這就叫做數據規模和臨時變量數目無關。就是說空間複雜度是O(1)。

空間複雜度 O(n)
我們先看一個代碼:

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
   j = i;
   j++;
}

這段代碼中,第一行new了一個數組出來,這個數據佔用的大小爲n,

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