開始之前有兩個知識點要明確一下:
1、時間復雜度可以根據程序運行的次數來判斷
2、時間復雜度的系數可以忽略
比如下面這個例子:
第一種情況程序只運行了一次,第二種情況程序運行了三次所以應該是O(3*1)=O(3),而系數可以忽略,所以最終結果就是O(1).
下面是常用的幾種時間復雜度
接着我們還是舉例子來看,下面的第一個程序循環了n次,所以它的時間復雜度是O(N),如果n等於5那么,就執行了5次,那么時間復雜度就是O(5),也就是常數復雜度O(1)。
第二個我們發現它是一個循環中又嵌套了一個循環,而且兩次循環的次數都是n所以它的時間復雜度就是n的平方,因為i=1時要輸出n次,等於2的時候也要輸出n次…所以是n個n相加那就是n 乘n也就是n的平方,如果再嵌套一個n次的循環它就是n的三次方。
在這兒我們做一下小拓展,就是如果我們把第二個程序的兩個循環改成並列關系,那么它的時間復雜度又是多少呢?
毫無疑問它執行了n次,又執行了n次,那就是2n次,根據上面的規則時間復雜度就是O(N)。
簡而言之,也就是如果是嵌套執行,嵌套幾次時間復雜度就是O(n的多少次方)
不管並列多少次,它的時間復雜度都是O(N)
我們還是接着看例子,如果我們把第一個程序的n改為4,那么這個函數體執行幾次呢?大家不妨找張紙算一算,其實挺簡單的,你只要明白4<4是不成立的就行,哈哈哈哈哈,所以他是執行了2次,所以他的執行次數就是log(n),那么時間復雜度就是O(log(n))這兒是以2為底的。
第二個是斐波那契數列代表的遞歸的時間復雜度,我們在后面講
時間復雜度曲線
我們可以看到當n小於5的時候時間復雜度其實都是差不多的,但是隨着n越來越大,你會發現指數級的它漲的是非常快的,也就是大家在寫程序的時候如果可以將一個時間復雜度為2的n次方,降到n的平方,那么你的收益是非常高的。
所以我們需要反復強調一個點,就是大家在寫程序的時候一定要對自己程序的時間復雜度和空間復雜度有所了解,而且是養成習慣,寫完了以后能夠下意識的分析出這段程序的時間和空間復雜度,還有就是能夠用最簡潔的時間,空間復雜度完成這段程序的話,基本上是一個頂尖職業選手的必備素養。
下面我們來看遞歸函數的時間復雜度
為了更好的表示我們進行遞歸的過程,我們需要畫一個叫做遞歸樹的東西來輔助我們理解整個程序
下面我們來看一個例子
這是一個求斐波那契數列的第n項的函數,我們來看它的時間復雜度,假如n等於6,那么直接跳到
fib(5)+fib(4)
而分別求5和4的時候又要分成兩步,我們看上面這個樹狀圖,每一次每個結點都要分成兩步,也就是第一層只有1個,第二層變成兩個,第三層變成四個,第四層變成八個,也就是指數函數
主定理
主定理是用來計算遞歸函數的時間復雜度的,下面給出了四種常用算法的時間復雜度
分別是
1、二分查找,一般發生在一個有序數列中找到你要的目標數,所以它每次都一分為二,只查一邊
2、二叉樹的遍歷,相當於把每個元素訪問了有且僅有一遍
3、有序二維矩陣的二分查找
4、歸並排序
答:上面四種情況,除了二分查找的時間復雜度是logn以外,其他三種的時間復雜度均為O(N),因為要訪問有且僅有一次其中的結點,其中的N為結點數。
以上圖片來自極客時間