递归回溯
N皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列…直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解…如此后,即可找出一个n皇后问题的所有可行解。
判断位置合法
每行只放置唯一一个皇后,因此行是不存在冲突的,只需要判断列和对角线.对角线的时候判断:|row - i| = |colVals[row] - colVals[i]|
class Solution {
/**
* Get all distinct N-Queen solutions
* @param n: The number of queens
* @return: All distinct solutions
* For example, A string '...Q' shows a queen on forth position
*/
ArrayList<ArrayList<String>> solveNQueens(int n) {
// write your code here
ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
if( n<0 )
return res;
int cols[] = new int[n];
placeQueen(n,res,0,cols);
return res;
}
public void placeQueen(int n, ArrayList<ArrayList<String>> res,int row, int []cols){
if(row == n){ //摆放完成,递归返回
ArrayList<String> path = new ArrayList<String>();
for(int i = 0;i < n ;i++){
String s = "";
for(int j = 0;j < n ;j++){
if(j == cols[i])
s = s + "Q";
else
s = s + ".";
}
path.add(s);
}
res.add(path);
}else{
for(int i = 0;i < n;i++){
cols[row] = i; //标记皇后
if(isValid(row,cols))
placeQueen(n,res,row + 1 ,cols); //摆放下一个皇后
}
}
}
//判断某点能否放置皇后
public boolean isValid(int row ,int[] cols){
for(int i=0;i<row;i++){
//检查列
if(cols[row] == cols[i] || Math.abs(cols[row] - cols[i]) == row - i)
return false;
}
return true;
}
};