回溯算法--LeetCode-51 N皇后

題目鏈接:https://leetcode-cn.com/problems/n-queens/

皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。

給定一個整數 n,返回所有不同的 皇后問題的解決方案。

每一種解法包含一個明確的 n 皇后問題的棋子放置方案,該方案中 'Q' 和 '.' 分別代表了皇后和空位。

示例:

輸入: 4
輸出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。

ac的代碼,代碼註釋裏面有部分思路

    public List<List<String>> solveNQueens(int n) {
        List<List<String>> result = new ArrayList<>();
        int[] x = new int[n];
        reback(result, x, 0);
        return result;
    }

    // 回溯算法
    // 1、由於每一行一定都會有一個皇后,因此只需要一個x[n]便能確定每個皇后的位置,x數組記錄每一行的橫座標
    // 2、一行一行向下遞歸,rowNum記錄行號
    // 3、check方法對rowNum行的皇后位置進行校驗
    public static void reback(List<List<String>> result, int[] x, int rowNum) {
        if (rowNum == x.length) {
            generateResult(result, x);
            return;
        }
        int temp = x[rowNum];
        for (int i = 0, length = x.length; i < length; i++) {
            x[rowNum] = i;
            if (check(x, rowNum)) {
                reback(result, x, rowNum + 1);
            }
            x[rowNum] = temp;
        }
    }

    // 校驗 
    // 0、只需要驗證到row的前一行(因爲只有row之前放皇后了)
    // 1、x[i] == x[row] 校驗是否爲相同列
    // 2、row - i == Math.abs(x[row] - x[i]) 校驗與主對角線和副對角線是否相同
    public static boolean check(int[] x, int row) {
        for (int i = 0; i < row; i++) {
            if (x[i] == x[row] || row - i == Math.abs(x[row] - x[i])) {
                return false;
            }
        }
        return true;
    }

    //生成結果
    public static void generateResult(List<List<String>> result, int[] x) {
        List<String> temp = new ArrayList<>();
        for (int i = 0,length = x.length; i < length; i++) {
            StringBuffer stringBuffer = new StringBuffer();
            for (int j = 0; j < length; j++) {
                if(j != x[i]) {
                    stringBuffer.append('.');
                    continue;
                }
                stringBuffer.append('Q');
            }
            temp.add(stringBuffer.toString());
        }
        result.add(temp);
    }

 

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