衆所周知,在算法競賽以及有關計算機科學的諸多學科中,時間複雜度和空間複雜度是評判一個算法/程序的重要標準。通常使用O( )來表示。算法
同一問題可用不一樣算法解決,而一個算法的質量優劣將影響到算法乃至程序的效率。算法分析的目的在於選擇合適算法和改進算法。數組
計算機科學中,算法的時間複雜度是一個函數,它定量描述了該算法的運行時間。這是一個關於表明算法輸入值的字符串的長度的函數。時間複雜度經常使用大O符號表述,不包括這個函數的低階項和首項係數。使用這種方式時,時間複雜度可被稱爲是漸近的,它考察當輸入值大小趨近無窮時的狀況。——來自百度百科的神奇解釋?數據結構
空間複雜度(Space Complexity)是對一個算法在運行過程當中臨時佔用存儲空間大小的量度,記作S(n)=O(f(n))。好比直接插入排序的時間複雜度是O(n^2),空間複雜度是O(1) 。而通常的遞歸算法就要有O(n)的空間複雜度了,由於每次遞歸都要存儲返回信息。一個算法的優劣主要從算法的執行時間和所須要佔用的存儲空間兩個方面衡量。函數
是否是感受很晦澀呢?優化
先來講說時間複雜度spa
根據大佬們的說法oi官方評測機的主頻是4.7GHZ,也就是說一秒鐘內能完成10^9程度的運算。並且在算法競賽裏面每每將運行時間卡在一秒鐘,這就意味着咱們須要結合題目中的數據範圍選擇儘量優秀的算法和數據結構等等以即可以得到所有分(固然暴力拿部分分也是要優化的)blog
事實上,一個程序的時間複雜度是基於你輸入的n,對它進行重複操做的次數。大O表示法隨着輸入的值變化,程序運行所須要的時間與輸入值的變化關係。通常咱們在計算時間複雜度的時候,能夠先找找程序的基本操做,例如:for循環是從1~n的循環,因此每次進行一次for,複雜度+n。可是當for循環套for循環的時候,複雜度就會以指數增加,通常是一重for,n的指數就加1。這種複雜度咱們通常稱之爲線性。排序
還有一些算法如最典型的二分,由於二分每次操做均可以把目標的元素砍掉一半,好比n=1024時,咱們只要找10次就能夠了,由於2^10=1024。那你又會說了,若是元素再大,次數還會這麼少嗎?您看呀,若是n=2048。那不就是2^11嗎?不難發現,元素的個數雖然翻倍,可是咱們只是多加了一次操做,因此O(logN)的對數算法不失爲一種很高效的算法。遞歸
其餘的一些複雜度如O(1)咱們通常稱之爲常數複雜度。例如一個數組a[5]={1,2,3,4,5}咱們要查詢數組的第一個元素1,由於它已經存好了元素,咱們的查詢只須要1次操做。例如ST表查詢RMQ就是O(1)的時間複雜度。由於這種算法就像一個小常數同樣,不會受到任何東西的影響,咱們把它稱之爲常數複雜度。字符串
最後還有線性對數複雜度 O(N*logN),在高效的排序中較爲常見,如快速排序,歸併排序,堆排序。
按數量級遞增排列,常見的時間複雜度有:
常數階O(1),對數階O(log2n),線性階O(n),線性對數階O(nlog2n),平方階O(n^2),立方階O(n^3)k次方階O(n^k),指數階O(2^n)以及O(n!)
再來講說空間複雜度
遞歸深度N*每次遞歸所要的輔助空間, 若是每次遞歸所需的輔助空間是常數,則遞歸的空間複雜度是 O(N).