Leetcode P0051"N-Queens" 题解

2020/08/25 Leetcode

博文中会简要介绍Leetcode P0051题目分析及解题思路。

“N-Queens”是其实算是p0052的变形题。p0052只需要统计解法个数,而这一道题需要统计所有的解法。和p0052一样,直接使用DFS算法探索即可。

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

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.

以下是Java的题解代码实现。

class Solution {
    public List<List<String>> solveNQueens(int n) {
        if (n == 0)
            return this.solutions;
        
        List<StringBuilder> board = new ArrayList<>();
        for (int count=0; count<n; ++count) {
            StringBuilder row = new StringBuilder();
            for (int itr=0; itr<n; ++itr)
                row.append('.');
            
            board.add(row);
        }
        
        this.dfs(board, 0);
        
        return this.solutions;
    }
    
    private List<List<String>> solutions = new ArrayList<>();
    // Directions Mapping
    // private int[][] directions = new int[][] 
    //{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1};
    
    private void dfs(List<StringBuilder> chessboard, int currRow) {
        if (currRow >= chessboard.size()) {
            List<String> solution = chessboard.stream().map((row) -> row.toString()).collect(Collectors.toList());
            
            this.solutions.add(solution);
            return;
        }
        
        for (int col=0; col<chessboard.size(); ++col) {
            if (this.validate(chessboard, currRow, col, chessboard.size())) {
                chessboard.get(currRow).setCharAt(col, 'Q');
                this.dfs(chessboard, currRow+1);
            }
            
            chessboard.get(currRow).setCharAt(col, '.');
        }
    }
    
    private boolean validate(List<StringBuilder> chessboard, int currRow, int currCol, int size) {
        for (int[] di: directions) {
            int nextRow = currRow+di[0];
            int nextCol = currCol+di[1];
            while (nextRow >= 0 && nextRow < size 
                   && nextCol >=0 && nextCol < size) {
                
                if (chessboard.get(nextRow).charAt(nextCol) == 'Q')
                    return false;
                
                nextRow += di[0];
                nextCol += di[1];
            }
        }
        
        return true;
    }
}

以下是C++的题解代码实现。

class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<string> board(n, string(n, '.'));
        if (n > 0)
            this->Dfs(board, n, 0);
        return solutions;
    }
    
private:
    vector<vector<string>> solutions;
    
    bool Validate(const vector<string> &board, int cur_row, int cur_col) {
        int dr[] = {-1, -1, 1, 1};
        int dc[] = {-1, 1, 1, -1};
        int bound = board.size();
        
        // Validate diagonal
        for (int di=0; di<4; ++di) {
            int next_row = cur_row+dr[di];
            int next_col = cur_col+dc[di];
            
            while (next_row >= 0 && next_row < bound 
                   && next_col >= 0 && next_col < bound) {
                if (board[next_row][next_col] == 'Q')
                    return false;
                
                next_row += dr[di];
                next_col += dc[di];
            }
        }
        // Validate colume
        for (int row=0; row<cur_row; ++row) {
            if (board[row][cur_col] == 'Q') 
                return false;
        }
        
        return true;
    }
    
    void Dfs(vector<string> &board, int n, int cur_row) {
        if (n == 0) {
            solutions.push_back(board);
            return;
        }
        else {
            for (int col=0; col<board[0].length(); ++col) {
                if (this->Validate(board, cur_row, col)) {
                    board[cur_row][col] = 'Q';
                    this->Dfs(board, n-1, cur_row+1);
                    board[cur_row][col] = '.';
                }
            }
        }
        
        return;
    }
};

Search

    Table of Contents