1.什麼是演算法(alorithm)
數學領域裡:演算法是用於解決某一類問題的公式和思想
計算機領域裡:它的本質是一系列程式指令,用於解決特定的運算和邏輯問題
2.演算法有高效的,也有拙劣的
衡量演算法好壞的重要標準有兩個:時間複雜度和空間複雜度
演算法的應用領域:(1)數**算還不簡單?,其實不然比如求兩個數的最大公約數,要求做到效率的極致;求兩個超大整數的和,不導致變數溢位,也要進行思考
(2)查詢(3)排序(4)最優決策:求迷宮最佳路線等(5)面試(如果這條也算的話):考察你對計算機底層知識的了解or你的邏輯思維能力
3.什麼是資料結構
data structure ,是演算法的基石,是資料的組織,管理和儲存格式,使用目的是為了高效地訪問和修改資料
組成方式有哪些?
(1)線性結構
線性結構是最簡單的結構,包括陣列,鍊錶,以及衍生出來的棧,佇列,雜湊表
(2)樹
稍微有些複雜,有代表性的是二叉樹
(3)圖
更複雜的資料結構,呈現多對多的關聯關係
(4)其他
各種由基本資料結構變形而來,用於解決某些特定問題
一,時間複雜度
1.演算法的好與壞:
舉個例:乙個**執行一次花100ms,占用記憶體5mb
乙個**執行一次花100s,占用記憶體500mb
後者可以收拾東西走人了
衡量程式的好壞的重要因素:執行時間的長短和占用記憶體空間的大小
2.基本操作執行次數
(1)乙個麵包10cm,2分鐘吃掉1cm,吃掉整個麵包要多久?2*10即20分鐘
如果麵包長度為ncm,所以為2*n
用乙個函式表達所需時間,可以記作t(n)=2n
(2)乙個16cm的麵包,5分鐘吃掉麵包剩餘長度的一半,即第5分鐘吃掉8cm,第10分鐘吃掉4cm,第15分鐘吃掉2cm,那麼吃到只剩1cm,需要多久?
這個問題化成數學問題即,16一直除以2,那麼除幾次結果等於1?涉及對數,即以2為底16的對數
所以到1cm即5*log16即20分鐘
用乙個函式表達所需時間,可以記作t(n)=5logn
(3)乙個長度為10cm的麵包和乙個雞腿,每兩分鐘吃掉乙個雞腿,那麼吃掉整個雞腿需要多久?
當然是2分鐘,這裡只要求吃雞腿,和麵包沒有關係
用乙個函式表達所需時間,可以記作t(n)=2
(4)乙個10cm的麵包,吃第乙個1cm花1分鐘,吃第二個1cm花2分鐘,每吃1cm所花時間就比上次多1分鐘,即1累加到10的綜合,也就是55分鐘。
如果麵包長度為n呢?1+2+3+...+(n-1)+n
用乙個函式表達所需時間,可以記作t(n)=0.5n^2+0.5n
上面講的是吃東西花費的時間,這個思想同樣適用於對程式基本操作執行次數的統計
設t(n)為基本操作執行次數的函式(也可以認為是程式的相對執行時間函式),n為輸入規模,
3.漸進時間複雜度:
若存在函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等於零的常數,則稱f(n)時t(n)的同量級函式,記作t(n)=o(f(n)),稱為o(f(n)),o為演算法的漸進時間複雜度,簡稱為時間複雜度
直白的說,時間複雜度就是把程式的想對執行時間函式t(n)簡化為乙個數量級,這個數量級可以時n,n^2,n^3等
如何推導出時間複雜度呢?遵循一下幾個原則:
(1)如果執行時間是常數量級,則用常數1表示
(2)只保留時間函式中的最高端項
(3)如果最高端項存在,則省去最高端項前面的係數
例如:t(n)=3n,最高端項為3n,省去係數3,則轉化成t(n)=o(n)
t(n)=5logn,最高端項為5logn,省去係數5,則轉化成t(n)=o(logn)
t(n)=2,只有常數量級,則轉化成t(n)=o(1)
t(n)=0.5n^2+0.5n,最高端項為0.5n^2,省去係數0.5,則轉化成t(n)=o(n^2)
所以當n足夠大時誰用時更長,誰更節省時間呢?
o(1)o(1)就是最低的時空複雜度了,也就是耗時/耗空間與輸入資料大小無關,無論輸入資料增大多少倍,耗時/耗空間都不變。 雜湊演算法就是典型的o(1)時間複雜度,無論資料規模多大,都可以在一次計算後找到目標(不考慮衝突的話)衝突的話很麻煩的,指向的value會做二次hash到另外一快儲存區域
二,空間複雜度
1.什麼是空間複雜度:簡單來說,空間複雜度就是執行演算法的空間成本,是對乙個演算法在執行過程中臨時占用儲存空間大小的量度
舉個例子:給n個整數,其中有兩個是重複的,要求找出這兩個重複的整數31
2548
72一般最樸素的就是乙個雙重迴圈遍歷,每遍歷乙個新的整數就回顧之前遍歷過的所有整數,但是這個演算法的時間複雜度太高o(n^2)
為了提高演算法的效率,我們可以採用乙個中間資料
比如每遍歷乙個整數,就把這個數存起來,放到字典裡,不用再和之前的比對,只需要直接查詢,看看是否有對應的整數即可
keyvalue31
1121
5141
9171
key代表整數的值,value代表出現的次數
當遍歷到最後乙個整數的時候很輕鬆就能找到2曾經出現過
keyvalue31
1122
5141
9171
因為讀寫字典的時間複雜度是o(1),所以整個演算法的時間複雜度是o(n),比雙重迴圈相比,執行效率增大了很多
但是記憶體空間是有限的,在時間複雜度相同的情況下,演算法占用的記憶體空間當然是越小越好
所以程式占用空間大小的計算公式記作s(n)=o(f(n)),n為問題規模,f(n)為演算法所佔空間的函式
2.空間複雜度的計算
(1)常量空間:空間大小固定,和輸入規模沒有直接關係的時候,空間複雜度記為o(1)
(2)線性空間:當演算法分配的空間是乙個線性的集合(如陣列),並且集合大小和輸入規模n成正比,時間複雜度為o(n)
(3)二維空間:當演算法分配的空間是乙個二維陣列的集合,並且集合長度和寬度都與輸入規模n成正比,時間複雜度為o(n^2)
(4)遞迴空間:是乙個比較特殊的場景,雖然沒有明顯的宣告變數或集合,但是計算機執行的時候,也會專門分出一塊記憶體,用來儲存「方法呼叫棧」,執行遞迴操作所需要的記憶體和空間和遞迴的深度是成正比的。純粹的遞迴操作的空間複雜度也是線性的,如果遞迴的深度是n,那麼空間複雜度就是o(n)
3.時間與空間的取捨
在絕大多數時候,時間複雜度更為重要一些,我們寧可多分配一些記憶體空間也要提高程式的執行速度
1 演算法複雜度
演算法是用於解決特定問題的一系列的執行步驟,使用不同演算法,解決痛乙個問題,效率可能相差非常大.package zh.algorithm public class fibonacci 方法2 迴圈,複雜度為o n public static int fib2 int n return second ...
演算法複雜度分析 1
空間複雜度 複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。如果存在常數c和n0使得當n n0時t n cf n 則記為t n o f n 例如 雖然對於較小的n值1000n要比n2大,但n2以更快地速度增長,因此n2最終將是更大的函式。在這種情況下,n 1...
演算法複雜度 時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...