力扣No.51 N皇后

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

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

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

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

示例:

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

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

皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

==================================================================================================

国际象棋中的皇后可以攻击一行、一列和斜线范围内的目标,因此下一行皇后的摆放需要考虑避开上面皇后的攻击范围。最终解法需要每一行都要有一个皇后,可能存在多种解法。这道题可以用回溯的方法来解决,从上往下搜索可能的解法,如果能到达底层则该解法成功,将其放入输出列表。如果发现某一行的某个位置与上面冲突,就往右搜索下一个;如果整行都找不到合适的解,就递归返回上一层再往下搜索。

 代码:

class Solution {
    public List<List<String>> solveNQueens(int n) {
        char[][] chess = new char[n][n];
        //先将矩阵置'.'
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                chess[i][j] = '.';
            }
        }
        List<List<String>> res = new ArrayList<>();
        dfs(0, chess, res);
        return res;
    }

    private void dfs(int row, char[][] chess, List<List<String>> res) {
        //如果能到达底层就加入结果
        if (row == chess.length) {
            res.add(construct(chess));
        }
        //每一行都从左往右搜索
        for (int col = 0; col < chess.length; col++) {
            //判断是否冲突
            if (isValid(chess, row, col)){
                chess[row][col] = 'Q';
                dfs(row + 1, chess, res);
                chess[row][col] = '.';
            }
        }
    }

    private boolean isValid(char[][] chess, int row, int col) {
        //判断这一列上面有没有皇后
        for (int i = 0; i < row; i++) {
            if (chess[i][col] == 'Q') {
                return false;
            }
        }
        //判断此位置右上角有没有皇后
        for (int i = row - 1, j = col + 1; i >= 0 && j < chess.length; i--, j++) {
            if (chess[i][j] == 'Q') {
                return false;
            }
        }
        //判断此位置左上角有没有皇后
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (chess[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }

    //把将char[][]转换为List<String>
    private List<String> construct(char[][] chess) {
        List<String> path = new ArrayList<>();
        for (int i = 0; i < chess.length; i++) {
            path.add(new String(chess[i]));
        }
        return path;
    }
}

 

posted @ 2020-11-05 16:23  豪哥的博客  阅读(73)  评论(0编辑  收藏  举报