常用算法總結
程序是為了具體的問題而存在,每個具體問題可抽象為一定的數學問題即算法的表示。故有了下面的公式:
程序 = 數據結構 + 算法 + 程序設計語言
數據結構表示要處理的數據;算法表示核心的處理流程;程序設計語言完成和具體業務化的問題。
常用的基本算法有以下這些:
1. 枚舉算法
枚舉法,將可能的所有解一一枚舉出來,每個去算法中計算,得出正確的解。
但是該算法效率不是很高,適用於一些沒有明顯規律的環境。
難點在於如果枚舉出所有可能的輸入。
算法思路:
- 對於一種可能的情況,計算其結果。
- 判斷結果是否滿足需求,如果不滿足要求,找出下一個可能的解代入第1步。如果滿足,則表示找到1個正確的解。
2. 遞推算法
遞推算法適用於有明確數學公式的情況,即通過已知條件,利用特定關系得出中間推論,直至得到結果的算法。
遞推算法分為順推和逆推兩種。
算法思路:
1.順推法:從已知條件出發,逐步推算出要解決的問題的方法叫順推。
典型的場景有:斐波那契數列.
2. 逆推法:從已知問題的結果出發,用迭代表達式逐步推算出問題的開始的條件,即順推法的逆過程,稱為逆推。
典型的場景有:分蛋糕問題
3. 遞歸算法
遞歸算法,就是一種直接或者間接地調用自身的算法。
遞歸算法的具體實現過程一般通過函數(或子過程)來完成,在函數(或子過程)的內部,編寫代碼直接或者間接地調用函數(或子過程)自己,即可完成遞歸操作。
算法思路:
把求解問題轉化為規模縮小了的同類問題的子問題,然后遞歸調用函數(或子過程)來表示問題的解,通過多次遞歸調用,最終可求出最小問題的解,然后通過這個最小問題的解返回上層調用,再求出次小問題的解,再返回上層調用,不斷重復,最終得到整個問題的解,完成遞歸操作
注意:遞歸算法必須有明確的遞歸出口。
4.分治算法
分治算法即把復雜問題簡單化,一個復雜的問題拆分為幾個相對簡單的子問題,如果子問題依然無法解決,再次分割。直到能夠解答問題為止。聽起來好像和遞歸算法沒有什么區別一樣?這兩者的差異在於分治法使用的子過程可以為多個,而遞歸只能是1個。在子問題一致時,兩者幾乎一致。而分治法產生的子問題,一定程度上和父問題相似,比較方便配合遞歸方法使用。
算法思路:
對於一個規模為N的問題,若該問題可以容易地解決(比如說規模N較小),則直接解決,否則將其分解為M個規模較小的子問題,這些子問題互相獨立,並且與原問題形式相同,遞歸地解這些子問題,然后將各子問題的解合並得到原問題的解。
故分治法會有3個典型步驟:分解,求解,合並。分治法的分解和合並步驟會影響其復雜度。
5.貪婪算法
貪婪算法是不考慮整體的情況下,只針對局部問題最優解的算法。一般情況下,貪婪算法的解不一定是問題的最優解。優勢是能夠節省時間。貪婪算法一般不需要回溯。
算法思路:
貪婪算法的基本思路:從問題的某一個初始解出發逐步逼近給定的目標,以盡可能快地求得更好的解。當達到算法中的某一步不能再繼續前進時,就停止算法,給出近似解
由貪婪算法的特點和思路可看出,該算法存在以下問題:
- 不能保證最后的解是最優的;
- 不能用來求最大或最小解問題;
- 只能求滿足某些約束條件的可行解的范圍。
6.試探算法
試探算法也叫回溯算法:為了求得問題的解,先選擇某一種可能情況進行試探,在試探過程中,一旦發現原來選擇的假設情況是錯誤的,就退回一步重新選擇,繼續向另一個方向試探,如此反復進行,直至得到解或證明無解。
以上這些基本就是算法設計中的基本思路:復雜問題分割為子問題或者分步驟,每個子問題尋找簡單的解決辦法。可能分治法需要優先考慮,將問題分解后,每個子問題再尋找解決方案,評估解決方案的准確性和算法復雜度時,決定采用貪婪還是回溯方法得到可以接受的解決方案。