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.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]先还是用矩阵保存每次的结果,然后转换成List<String>保存到solution中,然后再添加到List<List<String>>Solutions中
public class Solution {
boolean able_place(char[][] matrix, int place_row, int place_col){
for(int row = place_row-1; row >= 0; --row){
if(matrix[row][place_col] == 'Q') return false;
}
for(int row = place_row-1,col = place_col-1; row >= 0 && col >= 0; --row,--col){
if(matrix[row][col] == 'Q') return false;
}
for(int row = place_row-1,col = place_col+1; row >= 0 && col < matrix[0].length; --row,++col){
if(matrix[row][col] == 'Q') return false;
}
return true;
}
void NQueens(int n, int place_row, char[][] matrix,List<List<String>> solutions){
if(place_row >= matrix.length) return ;
for(int j = 0; j < matrix[0].length; ++j){
if(able_place(matrix,place_row,j)){
matrix[place_row][j] = 'Q';
if(place_row == matrix.length-1){
List<String> solution = new ArrayList<String>();
for(int i = 0; i < matrix.length; ++i){
String str = new String();
for(int jdx = 0; jdx < matrix[0].length; ++jdx){
str+=matrix[i][jdx];
}
solution.add(str);
}
solutions.add(solution);
}
NQueens(n,place_row+1,matrix,solutions);
matrix[place_row][j] = '.';
}
}
}
public List<List<String>> solveNQueens(int n) {
char[][] matrix = new char[n][n];
List<List<String>> solutions = new ArrayList<List<String>>();
for(int i = 0; i < matrix.length; ++i){
Arrays.fill(matrix[i],'.');
}
NQueens(n,0,matrix,solutions);
return solutions;
}
}
看到leetcode讨论区里更好的代码:
public class Solution {
private void helper(int r, boolean[] cols, boolean[] d1, boolean[] d2,
String[] board, List<String[]> res) {
if (r == board.length) res.add(board.clone());
else {
for (int c = 0; c < board.length; c++) {
int id1 = r - c + board.length, id2 = 2*board.length - r - c - 1;
if (!cols[c] && !d1[id1] && !d2[id2]) {
char[] row = new char[board.length];
Arrays.fill(row, '.'); row[c] = 'Q';
board[r] = new String(row);
cols[c] = true; d1[id1] = true; d2[id2] = true;
helper(r+1, cols, d1, d2, board, res);
cols[c] = false; d1[id1] = false; d2[id2] = false;
}
}
}
}
public List<String[]> solveNQueens(int n) {
List<String[]> res = new ArrayList<>();
helper(0, new boolean[n], new boolean[2*n], new boolean[2*n],
new String[n], res);
return res;
}
}
cols[c]=true表示c列不能再摆皇后,d1[id1]=true表示r行c列位置自左上向右下的的线上的点不能再摆,d1[id2]=true表示自坐下向右上的线上的点不能在摆。
从(r,c)向左再向下或者向右再向上移动时横纵坐标和值不变,向右再向下或向左再向上移动时横纵坐标差值不变。
其实r-c=const或者r+c=const也就是覆盖了不能再摆放皇后的点组成的一次函数。