本文對時間復雜度進行簡單的講解,主要在於簡單易懂。
一、算法效率的度量方法
1、事后統計方法
計算機 運行設計好的 測試算法的 程序和數據,得到運行時間。
缺陷:花時間 寫 算法的測試程序。
測試用的計算機性能有差別。編譯器產生的代碼質量。問題的輸入規模。
2、事前分析估算方法
依據統計方法對算法進行估算。
一個程序的運行時間依賴於算法的好壞和問題的輸入規模。(問題的輸入規模 是指輸入量的多少)
二、簡單分析
先看兩端代碼(本文demo是新建一個playground來寫的,用的swift),我們求1到n的和,可以用for循環從1加到n,也可以用公式:(n + 1) * n / 2 來算。如下:
1、第一種算法:
請點擊此處輸入圖片描述
2、第二種算法:
請點擊此處輸入圖片描述
3、分析
上面兩種算法,第一種要執行100次,而第二種只用執行一次。很明顯,第二種要比第一種效率更高。那么到底怎么來表示這兩種算法的效率呢,那就是時間復雜度。
算法的復雜度 不是精確的定位需要執行多少次,比如你在第二種算法中打印一萬次日志,那第二種算法是不是就不好了呢。 我們看的不是具體執行的行數,而是第一種循環了多少次,而第二種只需要一次執行。
如果看具體執行多少次語句,就要考慮編譯器優化等問題,語言的優劣,無關代碼等。
所以算法的復雜度 側重研究算法隨着 輸入規模擴大 而增長的一個抽象。不計 變量聲明、打印日志、循環索引的遞增和循環終止的條件 等。
在分析一個算法的運行時間時,重要的是把基本操作的數量和輸入模式 關聯起來。
上面2種方法隨着n的增大,執行的時間比 分別增長了n倍,和沒有變。所以我們可以理解為他們的復雜度分別為n 和 1。
如果兩個嵌套for循環的話,效率又是多少呢?如下:
請點擊此處輸入圖片描述
上面這個 外面每執行一次,里面就執行n次。所以效率是n*n。
三、算法的復雜度如何分析
上面只是簡單的說了3個例子,下面我們說下算法復雜度的分析方法。
1、忽略 加法常數
A算法: 2n+3
B算法:3n+1
當n不斷變大的時候:2n+3 基本和 2n 相同。 3n+1和 3n 基本相同。后面的加法常數 基本沒有影響。
所以時間復雜度要 忽略 加法常數。
2、忽略 相乘常數
4n 和 2n^2
當n不斷變大的時候:
其實 就是 n 和 n^2 的趨勢結果。
所以:於最高次項相乘的常數 並不重要,也可以忽略。不影響算法比較。
3、保留最高次項
2n^2+3n+1 和 2n^3+3n+1:
其實就是 n^2 和 n^3 的趨勢結果。
最高次項的 指數,函數隨着n的增長,結果也會變得增長特別快。
4、保留最高項階數
2n^2+3n+1 和 2n^2 ,當n變大,這兩個值幾乎相同。
判斷算法的效率時,函數中的常數和其他次要項常常可以忽略,而更應該關注主項(最高項)的階數。
四、算法時間復雜度
1、算法時間復雜度 的定義
下面是官方的定義,大家看看,如果覺得不好理解,就往下面看就好了。
在進行算法分析時,語句總的執行次數T(n) 是關於問題規模n的函數。
進而分析T(n)隨n的變化情況而確定T(n)的數量級。
算法的時間復雜度,也就是算法的時間量度。記作:T(n)=O(f(n))
它表示隨問題規模n的增大,算法執行時間的增長率和 f(n) 的增長率相同,稱作算法的漸進時間復雜度,簡稱為時間復雜度。 其中 f(n)是問題規模n的某個函數。
這樣用 大寫O() 體現時間復雜度 的記法, 稱為:大O記法。
隨着輸入規模 n 的增大,T(n)增長最慢的算法為最優算法。
文章開始的 三個求和算法的例子 (1 、 n 、n^2 )的時間復雜度 分別為: O(1) , O(n) , O(n^2)
2、如何分析一個算法的時間復雜度
2.1、用常數1 取代運行時間中的所有加法常數。
2.2、最修改后的運行次數函數中,只保留最高階項
2.3、如果最高階存在且不是1,則去除與這個項相乘的常數。
五、實戰分析
1、 下面代碼的時間復雜度是多少?
請點擊此處輸入圖片描述
是 O(4) ?
是錯的。只有O(1)。沒有O(2)、O(3)、O(4).
T(n) 是關於問題規模n的函數。print 和 n 是沒有關系的。所以答案是O(1)。
2、分析下面代碼的時間復雜度
請點擊此處輸入圖片描述
執行的次數:
n+(n-1)+(n-2)+….+1 = n(n+1)/2
分解:
n(n+1)/2 = n^2
根據剛才的 策略:
只保留最高項:所以 n/2 這項去掉。
去除與最高項相乘的常數:最終為: O(n^2)
3、對階數
請點擊此處輸入圖片描述
如果 有 X個2 相乘 后 >= n , 則會退出循環。
於是由 2^X = n 得到: X = log(2)n 。
所以 這個時間復雜度為 O(logn)
在各種不同算法中,若算法中語句執行次數為一個常數,則時間復雜度為O(1)。
另外,在時間頻度不相同時,時間復雜度有可能相同,如T(n)=n2+3n+4與T(n)=4n2+2n+1它們的頻度不同,但時間復雜度相同,都為O(n2)。
按數量級遞增排列,常見的時間復雜度有:常數階O(1),對數階O(log2n),線性階O(n), 線性對數階O(nlog2n),平方階O(n2),立方階O(n3),..., k次方階O(nk),指數階O(2n)。隨着問題規模n的不斷增大,上述時間復雜度不斷增大,算法的執行效率越低。
4、最好、最差、平均 復雜度
舉例:在冒泡排序中,如果給的數據本來就是排好序的,那么用冒泡排序 只需要執行n次就可以完成。也就是最好時間復雜度為 O(n)。
一般我們說的算法復雜度的平均 就是最差的情況。也就是O(n2)。
所以 冒泡排序 的 最差、平均 時間復雜度: O(n2) 。最好時間復雜度: O(n)