1. 程式人生 > >關於時間復雜度空間復雜度的理解

關於時間復雜度空間復雜度的理解

理解 ++i 運行時間 數學 空間復雜度 時間復雜度 運算 min 匯編指令

對於非科班出身的人來說,在學習算法的時候經常會遇到的問題就是關於對事件空間復雜度的 理解。

「大 O 表示法」的準確的數學描述方式非常枯燥,我在這裏就不貼出來湊字數了,其實大 O 表示法的意思挺簡單的,就是表示:隨著輸入的值變化,程序運行所需要的時間與輸入值的變化關系。

我們先看第一個代碼,這是一個函數,輸入一個數組,輸出這個數組裏元數的和。

int count(int a[], int n) {
    int result = 0;
    for (int i = 0; i < n; ++i) {
        result += a[i];
    }
    return result;
}
這裏的時間復雜度是O(n),即隨著n的增長,O(n)也隨之線性增長,我們用O(n)來表示這種線性時間復雜度
接下來我們來看第二行代碼
int binary_search(int A[], int key, int imin, int imax)
{
    if (imax < imin) {
        return KEY_NOT_FOUND;
    } else {
        int imid = midpoint(imin, imax);
        if (A[imid] > key)
            return binary_search(A, key, imin, imid - 1);
        else if (A[imid] < key)
            return binary_search(A, key, imid + 1, imax);
        else
            return imid;
    }
}

對於這個程序來說,如果它處理 N 個元素求和所花的時間是 T,那麽它處理 N 2 個元素的和所花的時間是多少呢?是 T 2 嗎?

如果頭腦算不清楚,我們可以拿實際的數字來實驗,二分查找每次(幾乎)可以去掉一半的候選數字。所以假如 N = 1024,那麽它最多要找多少次呢?答案是 10 次,因為 2^10 = 1024,每次去掉一半,10 次之後就只剩下唯一一個元素了。

好,這個時候,如果元素的個數翻一倍,變成 2048 個,那麽它最多要找多少次呢?相信大家都能算出來吧?答案是 11 次,因為 2 ^ 11 = 2048。

所以在這個例子中,輸入的元素個數雖然翻倍,但是程序運行所花的時間卻只增加了 1,我們把這種時間復雜度要叫「對數」時間復雜度,用 O(logN) 來表示。

除了剛剛講的「線性」時間復雜度和「對數」時間復雜度。我們還有以下這次常見的時間復度數。

「常數」時間復雜度,例如返回一個有序數組中的最小數,這個數因為始終在第一個位置,所以就不會受到數組大小的影響,無論數組多大,我們都可以在一個固定的時間返回結果。

「線性對數」時間復雜度,即 O(N*logN),這個復雜度比較常見,因為常見的高效的排序算法,都是這個時間復雜度,比如快速排序,堆排序,歸並排序等。

之前我很多次在網上看到說把1000萬次運算當做實際的1s來運算。我的計算機主頻是2.5GHZ,所以每秒可以執行25億次匯編指令,加入每次循環裏面的代碼可以產生250條匯編指令,才能夠得到1s1千萬次循環的結果,不是很確定,有機會可以yongxcode試一下

總結一下學習時間復雜度的知識對於我們的工作有什麽用:

  1. 對於不同的數據規模,能夠決策采用不同的解決方案。

  2. 了解什麽情況下用暴力解法就能夠解決問題,避免寫復雜的代碼。

  3. 在寫代碼之前,就能夠預估程序的運行時間,從而可以知道是否能夠滿足產品需求。

  4. 在程序出現性能瓶頸時,能夠有解決方案而不是抓瞎。


參考 https://www.cnblogs.com/mafeng/p/6831731.html

關於時間復雜度空間復雜度的理解