LeetCode N皇后问题

关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxiangcyr/leetcode-answers


LeetCode题目:51. N-Queens
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

LeetCode N皇后问题_第1张图片
N-Queens

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]

以下代码的时间复杂度为 O(n!): NP 问题,相当于对n的位置求排列数。

class Solution {
    private List> result = new ArrayList<>();
    
    public List> solveNQueens(int n) {
        // 定义一个棋盘,1代表皇后,0代表空格
        int[][] board = new int[n][n];
        
        // 从第一行开始
        travel(board, n, 0);
        
        return result;
    }
    
    // 在第rowIdx行放置皇后
    public void travel(int[][] board, int n, int rowIdx) {
        
        // 遍历每一个可以使用的位置
        for(int colIdx = 0; colIdx < n; colIdx++) {
            if(isValidPosition(board, n, rowIdx, colIdx)) {
                
                // 放置皇后
                board[rowIdx][colIdx] = 1;
                
                // 到达最后一行,加入结果集
                if(rowIdx == n - 1) {
                    
                    List oneSolution = new ArrayList<>();
                    
                    for(int i = 0; i < n; i++) {
                        StringBuilder sb = new StringBuilder();
                        
                        for(int j = 0; j < n; j++) {
                            if(board[i][j] == 1) {
                                sb.append("Q");
                            } else {
                                sb.append(".");
                            }
                        }
                        
                        oneSolution.add(sb.toString());
                    }
                    
                    result.add(oneSolution);
                    
                }
                // 递归到下一行
                else {
                    travel(board, n, rowIdx + 1);
                }

                // backtracking 回溯
                board[rowIdx][colIdx] = 0;
            }
        }
    }
    
    // 判断在(rowIdx, colIdx) 是否可以放置皇后
    public boolean isValidPosition(int[][] board, int n, int rowIdx, int colIdx) {
        
        // 在垂直方向上已经有皇后了
        for(int i = 0; i < rowIdx; i++) {
            for(int j = 0; j < n; j++) {
                if(board[i][j] == 1) {
                    // 在同一列上有皇后了
                    if(j == colIdx) return false;
                    
                    // 写对角斜线上有皇后了
                    if(Math.abs(rowIdx - i) == Math.abs(colIdx - j)) return false;
                }
            }
        }
        
        return true;
    }
}

你可能感兴趣的:(LeetCode N皇后问题)