面試題目:時間複雜度

一,定義

時間複雜度:就是說執行算法需要消耗的時間長短,越快越好。在一個算法存在最好、平均、最壞三種情況,我們一般關注的是最壞情況,原因是最壞情況是任何輸入實例在運行時間的上界。

二,表示方法

一般用"大O符號表示法"來表示時間複雜度:T(n)=O(f(n)),n是影響複雜度變化的因子,f(n)是複雜度具體的算法。

三,如何推導出時間複雜度呢

1,如果運行時間是常數量級,用常數1表示;

2,只保留時間函數中的最高階項;

3,如果最高階項存在,則省去最高階項前面的係數

三,常見的時間複雜度量級

3.1,常數階O(1)

int a = 1;
int b = 2;
int c = 3;

我們假定每執行一行代碼所需要消耗的時間爲1個時間單位,那麼以上3行代碼就消耗了3個時間單位,那是不是這段代碼的時間複雜度爲O(n)呢 ?其實不是的,因爲大O符號表示法並不是用來表示算法的執行時間,它是用來表示代碼執行時間的增長變化趨勢。

3.2,線性階O(n)

for(i = 1; i <= n; i++) {
   j = i;
   j++;
}

第1行會執行1次,第2行和第3行會分別執行n次,總的執行時間也就是 2n + 1 次,那它的時間複雜度表示是 O(2n + 1) 嗎? No !
還是那句話:“大O符號表示法並不是用於來真實代表算法的執行時間的,它是用來表示代碼執行時間的增長變化趨勢的”。
所以它的時間複雜度其實是O(n);原則:只保留時間函數中的最高階項;如果最高階項存在,則省去最高階項前面的係數。

3.3,對數階O(logN)

int i = 1;
while(i < n) {
    i = i * 2;
}
//或:
for(int i = 1; i < n; i = i*2){
    printf("i = %d",i);
}

可以看到每次循環的時候 i 都會乘2,那麼總共循環的次數就是log2n,因此這個代碼的時間複雜度爲O(logn)。
這兒有個問題,爲什麼明明應該是O(log2n),卻要寫成O(logn)呢?
其實這裏的底數對於研究程序運行效率不重要,寫代碼時要考慮的是數據規模n對程序運行效率的影響,常數部分則忽略,同樣的,如果不同時間複雜度的倍數關係爲常數,那也可以近似認爲兩者爲同一量級的時間複雜度。

640?wx_fmt=png

3.4,線性對數階O(nlogN)

for(m = 1; m < n; m++) {
    i = 1;
    while(i < n) {
        i = i * 2;
    }
}

線性對數階O(nlogN) 其實非常容易理解,將時間複雜度爲O(logn)的代碼循環N遍的話,那麼它的時間複雜度就是 n * O(logN),也就是了O(nlogN)。

3.5,平方階O(n²)

for(x = 1; i <= n; x++){
   for(i = 1; i <= n; i++) {
       j = i;
       j++;
    }
}

把 O(n) 的代碼再嵌套循環一遍,它的時間複雜度就是 O(n²) 了。

3.6,立方階O(n³),K次方階O(n^k)

參考上面的O(n²) 去理解就好了,O(n³)相當於三層n循環,其它的類似。

3.8,指數階(2^n)

640?wx_fmt=png

四,常見算法對應時間複雜度

二分法查找,二叉樹遍歷,最優排序矩陣搜索,歸併排序

歡迎訂閱公衆號【從零開始學無線】,一起學習交流!

 

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