Question:
1.
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.."] ]» Solve this problem
2.
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
方法:
两个问题一回事,有趣的是后者比前者步骤少一步。
DFS是我使用的方法,当然,可以有其他的解法:backtracking,递归式backtracking。
需要注意的是:
1. 虽然象棋板是二维的,但是记录位置的board[]整型数组却是一维的。index表示行,数值表示列,刚刚好。
2. 进入到DFS中,便开始检查位置是否合格,检查方法:三种情况,横纵,斜对角左上到右下,右上到左下。
3. 巧妙的利用了一维数组存放二维元素的遍历,给出了一个对称的检验法:board[i] == board[row] || board[i]+i==board[row]+row || board[i]-i==board[row]-row。
4. DFS的遍历以行计算,以行跳出递归。
Code:
1.
public class Solution {
public ArrayList<String[]> solveNQueens(int n) {
// Start typing your Java solution below
// DO NOT write main() function
ArrayList<String[]> res = new ArrayList<String[]>();
int[] board = new int[n];
for(int i=0; i<n; i++) board[i] = -1;
dfs(res, board, 0, n);
return res;
}
private void dfs(ArrayList<String[]> res, int[] board, int row, int n){
if(row == n){
draw(res, board, n);
return;
}
for(int i=0; i<n; i++){
board[row] = i;
if(isValid(board, row)){
dfs(res, board, row+1, n);
}
}
}
private boolean isValid(int[] board, int row){
for(int i=0; i<row; i++){
if(board[i] == board[row] || board[i]-i==board[row]-row || board[i]+i==board[row]+row)
return false;
}
return true;
}
private void draw(ArrayList<String[]> res, int[] board, int n){
String[] strs = new String[n];
for(int i=0; i<n; i++){
String s = new String();
for(int j=0; j<n; j++){
s += board[i]==j?"Q":".";
}
strs[i] = s;
}
res.add(strs);
}
}
2.
public class Solution {
int res;
public int totalNQueens(int n) {
// Start typing your Java solution below
// DO NOT write main() function
res = 0;
int[] board = new int[n];
for(int i=0; i<n; i++) board[i] = -1;
dfs(board, 0, n);
return res;
}
private void dfs(int[] board, int row, int n){
if(row == n){
res++;
return;
}
for(int i=0; i<n; i++){
board[row] = i;
if(isValid(board, row))
dfs(board, row+1, n);
}
}
private boolean isValid(int[] board, int row){
for(int i=0; i<row; i++){
if(board[i] == board[row] || board[i]+i == board[row]+row || board[i]-i == board[row]-row)
return false;
}
return true;
}
}
小结:
注意检查方法如何与行数结合,还有第二个方法中全局变量的使用方法,都是细节。