先看一下N皇后问题
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[“.Q..”, // 解法 1
“…Q”,
“Q…”,
“..Q.”],
[“..Q.”, // 解法 2
“Q…”,
“…Q”,
“.Q..”]
]
解释: 4 皇后问题存在两个不同的解法。
思路
这种类型的问题其实主要是在于对于所有情况的一次遍历比如说我们可以看图
可以看到查找可以用的有效解的过程是深度优先搜索DFS的过程,其实就是递归进行搜索的过程,需要注意的是进行递归之后,为了重复利用空间,我们需要取消先前搜索过程中的建立的标记我们将所有遍历后的结果,打印出来就是这个题目的解法了
这个题目使用C语言去解题需要使用较为频繁的指针操作所以我们使用Java来解题
重点
需要注意的是
我们需要使用程序语言来描述皇后问题的具体要求,如果说我们现在有两个皇后的坐标分别是(x,y)(i,j),比如说同一横行的两个皇后,我们使用x==i来描述,同一个主对角线的两个皇后我们使用x-y==i-j来表示,而同一副对角线的两个皇后的位置关系我们使用x+y==i+j来表示,这是筛选的必要条件也是对于八皇后问题的数学抽象
class solution {
public List<List<String>> solveNQueens(int n) {
char [][] board =new char[n][n];//初始化棋盘
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]='.';
}
}
List<List<String>> res =new ArrayList<List<String>>();//创建存储结果的二二维List
dfs(board,0,res);//启动DFS
return res;
}
//先进行第一列的遍历,然后换第二列的不同行然后...
private void dfs(char [][] board,int colIndex,List<List<String>> res){
if(colIndex==board.length){//已经递归至最后一列
res.add(structList(board));
return ;
}
for(int i=0;i<board.length;i++){
if(validate(board,i,colIndex)){
board[i][colIndex]='Q';
dfs(board,colIndex+1,res);//递归遍历
board[i][colIndex]='.';//取消标记
}
}
}
//验证摆放棋盘的位置合法性
private boolean validate(char [][] board,int x,int y){
for(int i=0;i<board.length;i++){
for(int j=0;j<y;j++){
if(board[i][j]=='Q'&&(x+j==i+y||x+y==i+j||x==i))
return false;
}
}
return true ;
}
//将遍历结果进行格式化
private List<String> structList(char[][] board){
List<String> res =new LinkedList<String>();
for(int i=0;i<board.length;i++){
String s=new String (board[i]);
res.add(s);
}
return res;
}
}