4.渐进时间复杂度
分析算法時間復雜度的基本方法
1.找出語句頻度最大的那條語句作為基本語句;
2.計算基本語句的頻度,得到問題規模n的某一個函數;
3.取其數量級用O表示
忽略所有低次冪項和最高次冪的系數,這樣可以簡化算法分析,也體現出了增長率的含義。
- 常數階
實際上,如果算法的執行時間不隨問題規模n的增加而增長,算法中語句頻度就是某個常數。即使這個常數再大,算法的時間復雜度都是O(1)。
- 線性階
給小灰一個長度為10cm的面包,小灰每三分鐘吃掉1cm,那么他吃掉整個面包要多久?
答案自然是3*10=30min
如果面包的長度為n cm呢?
此時吃掉整個面包需要3*n即3n分鐘。
如果用一個函數來表達吃掉整個面包所需要的時間可以記作T(n)=3n
n表示面包的長度即處理的數據的規模
- 對數階
給小灰一個長度為16cm的面包,小灰小灰每5min吃掉面包剩余長度的一半,第1min吃掉8cm,第2min吃掉4cm,第三min吃掉2cm…那么小灰把面包吃得只剩下1cm,需要多少天呢?
這個問題翻譯一下,就是數字16不斷地除以2,除幾次以后的結果等于1?這里要涉及到數學當中的對數,以2位底,16的對數,可以簡寫為log216。(下文對函數的底數全部省略)
因此,把面包吃得只剩下1寸,需要 5log16=54=20 min
如果面包的長度為n cm呢?
此時吃掉整個面包需要5logn分鐘記作T(n)=5logn
也可以給n幾個具體的值找規律
- 平方階
由于當i=0時內循環執行n次,當i=1時內循環執行n-1次,…,當i=n-1時內循環執行1次總執行次數
n+(n-1)++(n-2)+…+1=n(n+1)/2
時間復雜度是O(n^2)
- 立方階
不太知道怎么算可以復習下級數求和
- 最好、最壞和平均時間復雜度
有的情況算法的基本操作重復執行的次數還隨問題輸入的數據集不同而不同
最好的情況a0=e執行1次
最壞數組中沒有e/an-1=e執行n次
而對于一個算法來說,需要考慮各種可能出現的情況,以及每一種情況出現的概率,一般情況下,可假設待查找的元素在數組中所有位置上出現的可能性均相同。類似于數學中求期望值。計算每一種情況執行次數與概率的乘積在求和。
最壞時間復雜度是指在最壞情況下算法的的復雜度;
最好時間復雜度是指在最好情況下算法的的復雜度;
平均時間復雜度是指算法在所有可能情況下,按照輸入實例以等概率出現時,算法計算量的加權平均值。
通常考慮最壞和平均但有時平均比較難計算只考慮最壞時間復雜度,最壞情況運行時間是一種保證,那就是運行時間不會再壞了。
計算公式
如果時間復雜度是平方階最好降低到對數階實在不行平方階也可以接受,立方階也尚可。
- 算法的空間復雜度:算法要占據的空間
- 算法本身要占據的空間:輸入/輸出、指令、常數、變量等。
- 算法要使用的輔助空間。
若輸入數據所占據的空間只取決于問題本身和算法無關,這樣只需分析該算法在實現時所需的輔助單元即可,若算法執行時所需的輔助單元相對于輸入數據量而言是個常數,則稱此算法為原地施工,空間復雜度為O(1)
- 時間與空間的取舍
舉個例子說,要判斷某年是不是閏年,你可能會花一點心思來寫一個算法,每給一個年份,就可以通過這個算法計算得到是否閏年的結果。
另外一種方法是,事先建立一個有2050個元素的數組,然后把所有的年份按下標的數字對應,如果是閏年,則此數組元素的值是1,如果不是元素的值則為0。這樣,所謂的判斷某一年是否為閏年就變成了查找這個數組某一個元素的值的問題。
第一種方法相比起第二種來說很明顯非常節省空間,但每一次查詢都需要經過一系列的計算才能知道是否為閏年。第二種方法雖然需要在內存里存儲2050個元素的數組,但是每次查詢只需要一次索引判斷即可。
這就是通過一筆空間上的開銷來換取計算時間開銷的小技巧。到底哪一種方法好?其實還是要看你用在什么地方。
但在絕大多數情況下,時間復雜度更重要一些,我們寧愿多分配一些內存空間也要提升程序的執行速度。
總結
- 上一篇: 百度杀毒软件2013低调发布
- 下一篇: 为什么HTTPS通信中需要CA机构颁发的