LeetCode-51.N皇后(相关话题:回溯算法)

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

示例:

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

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

解题思路:利用四个辅助数组line[n]、col[n]、left[2n-1]、right[2n-1],分别记录第i行、第i列、从上往下数第i条左斜线、从上往下数第i条右斜线是否有皇后,左右斜线下标i与元素下标[h, l]的关系如下图(右斜线是将计算结果取绝对值):

然后进行深度优先搜索

java代码:

class Solution {
    public List> solveNQueens(int n) {
        boolean[] line = new boolean[n];//line[i]记录第i行是否有皇后
        boolean[] col = new boolean[n];//col[i]记录第i列是否有皇后
        boolean[] leftDiagonal = new boolean[2*n-1];//leftDiagonal[i]记录从上往下数第i条左斜对角线是否有皇后
        boolean[] rightDiagonal = new boolean[2*n-1];//rightDiagonal[i]记录从上往下数第i条右斜对角线是否有皇后
        char[][] tmp = new char[n][n];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n;j++)
                tmp[i][j] = '.';
        }


        List> res = new LinkedList<>();
        dfs(tmp,0, 0, res, line, col, leftDiagonal, rightDiagonal);
        return res;
    }
    private void dfs(char[][] hang, int s, int queen, List> res, boolean[] line, boolean[] col, boolean[] left, boolean[] right){
        int n = line.length;

        for(; s < n*n; s++){
            int h = s/n, l = s%n;
            if(line[h] || col[l] || left[h+l] || right[Math.abs(l-h-(n-1))]){
                continue;
            }

            hang[h][l] = 'Q';
            queen++;
            line[h] = true;
            col[l] = true;
            left[h+l] = true;
            right[Math.abs(l-h-(n-1))] = true;
            dfs(hang, s+1, queen, res, line, col, left, right);

            hang[h][l] = '.';
            queen--;
            line[h] = false;
            col[l] = false;
            left[h+l] = false;
            right[Math.abs(l-h-(n-1))] = false;
        }

        if(n == queen){
            List tmp = new ArrayList<>(4);
            for(int i = 0; i < n; i++){
                tmp.add(new String(hang[i]));
            }
            res.add(tmp);
        }
    }
}

注:该种解法运行效率较慢(130ms),但是目前未想到好的优化思路,后续如果有做算法优化,会更新此文。

你可能感兴趣的:(LeetCode,Java)