一、算法復雜度的概念
1、空間復雜度
算法運行所需要的內存空間,它和算法每次運行的數據數目或者說程序段所需要的變量個數成正比。
2、時間復雜度:算法的主要衡量指標,它主要和算法實現所需要的指令個數成正比。在分析算法時間復雜度的時候,一般用O(讀作大o符號)進行表示。
大O符號表示這樣一種概念:某個算法他運行所需要的運算量的級別,大O符號的表示通常忽略常數項或者低次項而主要考察最高次項的運算量級別數。例子:
1 for(int i = 0;i<n;i++){ 2 //這里具體代碼一 3 n++;//第一步 4 n--;//第二步 5 . 6 . 7 . 8 //第k步 9 }
這里的算法復雜度為:kn;由於這里k是常數,所以分析的時候一般忽略常數k,而直接表示為O(n);表示該算法只是和輸入數據量的大小n有關,並且運算數量級為n。
再例如:當實際的算法運算復雜度為an^2+bn+k中,分析的時候通常會忽略低次項n和常數項k,另外a、b的系數也不用考慮,我們分析的時候,只是分析算法的運算的數量級而已;
3、空間VS時間:很多 時候,我們發覺,某個算法在改造之前和改造之后,會存在一種這樣的關系:空間變小,時間必然變大;反之亦然。其實,空間復雜度和時間復雜度本來就是矛盾的,不可能在同時提高兩者的,后面的算法總結中我會提到這個問題(裝個逼咯)
二、常用算法關系與表達式之間的關系
1、logN(注意,算法分析中,通常lgN的意義和數學的lgN有區別,算法中lgN通常是表示log2 N(這里2為底數))的對應情況:
大規模問題中,每步都將問題規模縮小n倍(對應log中底數為n,例如二分法找最值的對應復雜度為lgN),則算法復雜度課用上面算式表示
(特別說明:lg2還有以下的含義:十進制表示為二進制所需要的位數,logk N:十進制表示為k進制所需要的位數)
2、N:輸入的所有數據均需要全部處理方可解決問題的情形
3、Nlogn N:1和2情況的組合,它表示如下意義:大規模問題進行n步分解后,每步所需要的執行次數是logN。
4、N^k:一半出現在k層循環嵌套中
三、常用的遞推關系
1、斐波那契數列:Fn=Fn-1 + Fn-2;
2、Cn-C(n/2) = 1:對應二中的情況1:每次問題規模減半(如果對應3中的情形,相當於每次的運算規模或者說算法的輸入減半,但是每次都要檢查某個數據,結合二分法理解:二分法每次都要檢查一個數字即可使得下一步的問題規模縮小);Cn=lgN
3、Cn-C(n/2) = n:每次的運算規模或者說算法的輸入減半,但是每次都要檢查所輸入的數據;結果:Cn=n + n/2 + + n/4 + n/8+...(用累加法解答),化簡后得到結果Cn=2n;
4、Cn-2C(n/2)=n:每次將問題的規模平均成兩半,但是,每次都需要比較兩個部分(平均分后的兩個部分的數據)的每一個數據(可以結合快速排序的最好情形進行理解),這個其實是對應二中的情況3(此時n取2):每次平均為兩份(相當於規模減半),但是呢,減半的兩個部分都必須比較每個數據方可繼續減半下去(遞歸下去)。(有點抽象,最好還是結合快速排序理解)
5、Cn-2Cn=1當4中的n為1(表示分半猴只需做常量級別的數據比較工作)時,對應結果為Cn=n
四、算法的其他概念
1、最好 or 平均 or 最壞:一般分析都是當成最壞情形,因為算法設計需要保守地考慮最壞情形;
2、遞推公示的求解技巧
A、轉化:一般會轉化為等差、等比數列
B、變形技巧(以達到A的目的):有指數出現就取對數(一般會出現與2^n相關時);連加/乘推出關系;
(好吧,這些有點偏理論了,忽略吧!)