8皇后問題,92種可能(java 回溯)看不懂算我輸系列

在這裏插入圖片描述

  • 代碼比較少,幾乎一比一的註釋,可以多看兩遍,debug試試。
public class Solution0812 {

    public static void main(String[] args) {
        Solution0812 solution = new Solution0812();
        solution.eightQueen(8);
    }

    private int count = 0;

    private void eightQueen(int n) {
        //初始化,所有的格子填充一個點
        char[][] queen = new char[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                queen[i][j] = '.';
            }
        }
        //從第0行開始安排 Queen 的擺放位置
        backtrack(queen, 0, n);
    }

    private void backtrack(char[][] queen, int i, int n) {
        if (i == n) {
            //已經進行到第n行,則表示滿足規則,棋盤已經列舉完畢,進行棋盤打印,並返回
            count++;
            System.out.println("第" + count + " 種可能: " + Arrays.deepToString(queen));
            return;
        }
        //j是列數,表示預計在【i,j】放上下一個 Queen
        for (int j = 0; j < n; j++) {
            //判斷在【i,j】放一個 Queen ,是否有效可行,如果不可行,則 j++,換下一列試試
            if (!judge(queen, i, j)) continue;
            //如果可行,則在【i,j】處放一個 Queen
            queen[i][j] = 'Q';
            //繼續進行下一行 Queen 的位置擺放,因爲在這一行肯定只能放一個 Queue
            backtrack(queen, i + 1, n);
            //如果棋盤全部擺放結束,或者嘗試在第【i + 1,j】,j 從0-n (前閉後開)擺放Queue,都不可行
            //則需要進行回溯,即第i行的 Queen 需要換一個位置擺放
            //回溯,將【i,j】的Queen還原爲'.',遍歷嘗試在【i,j+1】位置擺放一個Queen
            //回溯的本質是枚舉所有可能情況(並進行適當剪枝,去掉不可能的路徑,返回上一步,繼續枚舉)
            queen[i][j] = '.';
        }
    }

    /**
     * 判斷在【i,j】放一個queen,是否有效可行
     */
    private boolean judge(char[][] queen, int i, int j) {
        //在 i 這一行只能放一個 Queen ,之前已經做過處理
        //在 j 這一列只能放一個 Queen ,如果檢測到這一列有 Queen ,則不可行,返回false
        for (int k = 0; k < i; k++) {
            if (queen[k][j] == 'Q')
                return false;
        }
        //比較斜對角
        //往左上角方向延伸,如果檢測到這一條對角線有 Queen ,則不可行,返回false
        for (int z = i - 1, k = j - 1; z >= 0 && k >= 0; z--, k--) {
            if (queen[z][k] == 'Q') return false;
        }
        //往右上角方向延伸,如果檢測到這一條對角線有 Queen ,則不可行,返回false
        for (int z = i - 1, k = j + 1; z >=0 && k <  queen.length; z--, k++) {
            if (queen[z][k] == 'Q') return false;
        }
        //行、列、對角線都匹配完成,返回true,表示【i,j】處可以放置一 個Queen
        return true;
    }
}

輸出結果:
總共92種解法
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章