回溯算法--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);
    }

 

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