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.."] ]
很经典的题了,在CTCI上面有道一模一样的。
以8x8棋盘为例。由于放queen的顺序与结果无关,因此假设棋子是按照从row(0)到row(7)的顺序进行摆放的。这样在处理最后一行时有8种可能的摆放方法:
ways to place 8 queens on a 8x8 board=
ways to place 8 queens on a 8x8 board with a queen at (7,0)+
ways to place 8 queens on a 8x8 board with a queen at (7,1)+
...
ways to place 8 queens on a 8x8 board with a queen at (7,7)
上面的每一种摆放方法又可以继续分为更多的情况,比如以最后一行放在(7,0)为例,
ways to place 8 queens on a 8x8 board with a queen at (7,0) =
ways to place 8 queens on a 8x8 board with a queen at (7,0) and another at (6,1)+
....
ways to place 8 queens on a 8x8 board with a queen at (7,0) and another at (6,7)
这样子下去就可以一行一行地递归来得到结果了。
public class Solution {
public List<String[]> solveNQueens(int n) {
List<String[]> result = new ArrayList<String[]>();
String[] solution = new String[n];
placeQueens(0, n, result, solution);
return result;
}
public void placeQueens(int row, int n, List<String[]> result, String[] solution){
//found one solution
if(row == n){
result.add(Arrays.copyOfRange(solution, 0, n));
}
else{
for(int col = 0; col < n; col++){
if(checkValid(row, col, solution)){
addOneRow(solution, row, col, n);
placeQueens(row + 1, n, result, solution);
}
}
}
}
public boolean checkValid(int row, int col, String[] solution){
//have to check all the previous rows if violating rules with the current row
for(int i = 0; i < row; i++){
String line = solution[i];
//j is the column index of this row that the queen lies
int j = line.indexOf("Q");
//check if they are in the same column
if(col == j)
return false;
//check if they are in the same diagnol
int colDiff = Math.abs(j - col);
int rowDiff = row - i;
if(colDiff == rowDiff)
return false;
}
return true;
}
public void addOneRow(String[] solution, int row, int col, int n){
StringBuilder builder = new StringBuilder();
for(int i = 0; i < col; i++){
builder.append(".");
}
builder.append("Q");
for(int i = col + 1; i < n; i++){
builder.append(".");
}
solution[row] = builder.toString();
}
}