LeetCode-51. N-Queenshttps://leetcode.com/problems/n-queens/
题目描述
The n-queens puzzle is the problem of placing n
queens on an n x n
chessboard such that no two queens attack each other.
Given an integer n
, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space, respectively.
Example 1:
Input: n = 4 Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above
Example 2:
Input: n = 1 Output: [["Q"]]
Constraints:
1 <= n <= 9
解题思路
【C++】
遍历判别是否有效
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > res;
vector<string> nQueens(n, string(n, '.'));
solveNQueens(res, nQueens, 0, n);
return res;
}
private:
void solveNQueens(vector<vector<string>>& res, vector<string>& nQueens, int row, int &n) {
if (row == n) {
res.push_back(nQueens);
return;
}
for (int col = 0; col != n; ++col)
if (isValid(nQueens, row, col, n)) {
nQueens[row][col] = 'Q';
solveNQueens(res, nQueens, row + 1, n);
nQueens[row][col] = '.';
}
}
bool isValid(vector<string> &nQueens, int row, int col, int &n) {
//check if the column had a queen before.
for(int i = 0; i != row; ++i)
if(nQueens[i][col] == 'Q') return false;
//check if the 45° diagonal had a queen before.
for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; --i, --j)
if (nQueens[i][j] == 'Q') return false;
//check if the 135° diagonal had a queen before.
for (int i = row - 1, j = col + 1; i >= 0 && j < n; --i, ++j)
if (nQueens[i][j] == 'Q') return false;
return true;
}
};
保存有效状态,用空间换时间
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
if (n == 0) {return res;}
vector<string> board(n, string(n, '.'));
vector<bool> column(n, false), ldiag(2*n-1, false), rdiag(2*n-1, false);
backtracking(res, board, column, ldiag, rdiag, 0, n);
return res;
}
void backtracking(vector<vector<string>>& res, vector<string>& board,
vector<bool>& column, vector<bool>& ldiag, vector<bool>& rdiag,
int row, int n) {
if (row == n) {
res.push_back(board);
return;
}
for (int i = 0; i < n; i++) {
if (column[i] || ldiag[n-1-row+i] || rdiag[row+i]) {
continue;
}
board[row][i] = 'Q';
column[i] = ldiag[n-1-row+i] = rdiag[row+i] = true;
backtracking(res, board, column, ldiag, rdiag, row + 1, n);
board[row][i] = '.';
column[i] = ldiag[n-1-row+i] = rdiag[row+i] = false;
}
}
};
【Java】
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
if (n == 0) {return res;}
char[][] board = initBoard(n);
boolean[] column = new boolean[n];
boolean[] ldiag = new boolean[2*n-1];
boolean[] rdiag = new boolean[2*n-1];
backtracking(res, board, column, ldiag, rdiag, 0, n);
return res;
}
private char[][] initBoard(int n) {
char[][] board = new char[n][n];
for (char[] str: board) {Arrays.fill(str, '.');}
return board;
}
private List<String> convert(char[][] board) {
List<String> sol = new ArrayList<>();
for(int i = 0; i < board.length; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < board[0].length; j++) {sb.append(board[i][j]);}
sol.add(sb.toString());
}
return sol;
}
private void backtracking(List<List<String>> res, char[][] board,
boolean[] column, boolean[] ldiag, boolean[] rdiag,
int row, int n) {
if (row == n) {
res.add(convert(board));
return;
}
for (int i = 0; i < n; i++) {
if (column[i] || ldiag[n-1-row+i] || rdiag[row+i]) {
continue;
}
board[row][i] = 'Q';
column[i] = ldiag[n-1-row+i] = rdiag[row+i] = true;
backtracking(res, board, column, ldiag, rdiag, row + 1, n);
board[row][i] = '.';
column[i] = ldiag[n-1-row+i] = rdiag[row+i] = false;
}
}
}