算法九——回溯算法
文章出處:極客時間《數據結構和算法之美》-作者:王爭。該系列文章是本人的學習筆記。
理解回溯
在我們的一生中,會遇到很多重要的岔路口。在岔路口上,每個選擇都會影響我們今后的人生。有的人在每個岔路口都能做出最正確的選擇,最后生活、事業都達到了一個很高的高度;而有的人一路選錯,最后碌碌無為。如果人生可以量化,那如何才能在岔路口做出最正確的選擇,讓自己的人生“最優”呢?
我們可以借助前面學過的貪心算法,在每次面對岔路口的時候,都做出看起來最優的選擇,期望這一組選擇可以使得我們的人生達到“最優”。但是,我們前面也講過,貪心算法并不一定能得到最優解。那有沒有什么辦法能得到最優解呢?
2004 年上映了一部非常著名的電影《蝴蝶效應》,講的就是主人公為了達到自己的目標,一直通過回溯的方法,回到童年,在關鍵的岔路口,重新做選擇。當然,這只是科幻電影,我們的人生是無法倒退的,但是這其中蘊含的思想其實就是回溯算法。
回溯的處理思想,有點類似枚舉搜索,又被稱為“暴力搜索”。我們枚舉所有的解,找到滿足期望的解。為了有規律地枚舉所有可能的解,避免遺漏和重復,我們把問題求解的過程分為多個階段。每個階段,我們都會面對一個岔路口,我們先隨意選一條路走,當發現這條路走不通的時候(不符合期望的解),就回退到上一個岔路口,另選一種走法繼續走。
八皇后問題
在一個8x8的棋盤中,八個棋子(皇后)不能在同一行,同一列,對角線上相遇。第一幅圖是滿足要求的,第二幅圖是不滿足要求的。求八皇后所有的擺放方式。
我們把這個問題分成8個階段。依次將八個棋子放到第一行、第二行…。在放置過程中不停地檢查看當前位置是否滿足條件。如果不滿足就換另一種方式試。
public class EightQueens {public static void main(String[] args){new EightQueens().eightQueens();}public void eightQueens(){cal8queens(0);}private int[] result = new int[8];//下標表示第幾行,值表示皇后在第幾列private void cal8queens(int row) {if(row==8){printResult();}else{for(int j=0;j<8;j++){if(isOk(row,j)){result[row] = j;cal8queens(row+1);}}}}private boolean isOk(int row, int col) {//不在同一列int leftUp = col-1,rightUp=col+1;for(int i=row-1;i>=0;i--){if(i!=row && result[i]==col) return false;if(leftUp>=0 && result[i]==leftUp) return false;if(rightUp<8 && result[i]==rightUp) return false;leftUp++;rightUp--;}return true;}private void printResult() {for(int i=0;i<result.length;i++){System.out.println();for(int j=0;j<8;j++){if(j==result[i]){System.out.print("Q");}else{System.out.print("*");}System.out.print(" ");}}System.out.println();} }回溯法還可以適于練習的題目:0-1背包問題、正則表達式問題 。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: RGB/YUV/YCbCr--关于显示,
- 下一篇: Web项目,要求:保存用户名和密码在Co