【LeetCode-Medium-Java】面试题 08.12. 八皇后

题目

设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。

示例

 输入:4
 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
 解释: 4 皇后问题存在如下两个不同的解法。
[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]

解题思路:回溯算法

1、从第0行开始,该行上的每一列都做判断,判断是否满足不在其他皇后的攻击范围内。

2、回溯的大框架就是for循环里dfs,此题中的分支也就是for循环的内容是确定行的每一列都要判断是否能放Queen。dfs的内容是下一行的每一列。

3、接下来就是该如何判断i,j这个位置是否可以放置Queen。对于i行前的每一行,

     ①如果j列有Queen,则在攻击范围内,return false。

     ②如果j-1,j-2....j-n列有Queen,则在攻击范围内,return false

     ③如果j+1,j+2....j+n列有Queen,则在攻击范围内,return false

如果都没有,则该处i,j可以放置Queen。

代码

public static List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        char [][] board = new char[n][n];
        init(board);
        helper(res,board,0);
        return res;
    }

    private static void helper(List<List<String>> res, char[][] board, int rowIndex) {
        //终止条件:已经处理完最后一行
        if (rowIndex == board.length){
            res.add(generate(board));
            return;
        }
        //dfs
            //尝试往这一行的每一列上放置Queen
        for (int colIndex = 0;colIndex < board.length; colIndex++) {
                //此处是否可放置Queen
            if (isValid(board,rowIndex,colIndex)){
                board[rowIndex][colIndex]  = 'Q';
                helper(res,board,rowIndex + 1);
                //回溯
                board[rowIndex][colIndex]=',';
            }
        }
    }

    private static boolean isValid(char[][] board, int rowIndex, int colIndex) {
        //判断该行前的每一行Queen的位置是否可攻击此行
        //此列上是否有Queen
        for (int i = 0; i < rowIndex; i++) {
            if (board[i][colIndex] == 'Q')  return false;
        }
        //左上方对角线是否有Queen
        for (int i = rowIndex-1,j = colIndex -1; i >=0 && j>=0 ; rowIndex--,colIndex--) {
            if (board[i][j] == 'Q') return false;
        }
        for (int i = rowIndex -1 , j = rowIndex + 1; i >= 0 && j>=0 ; i--,j--) {
            if (board[i][j] == 'Q') return false;
        }
        return true;
    }

    private static List<String> generate(char[][] board) {
        List<String> list = new ArrayList<>();
        for (char [] row:board) {
            StringBuffer sb = new StringBuffer();
            for (char c:row) {
                sb.append(c);
            }
            list.add(sb.toString());
        }
        return list;
    }


    private static void init(char[][] board) {
        for (int i = 0; i < board.length; i++) {
            Arrays.fill(board[i],'.');
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_44284276/article/details/108884950