n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4 输出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] 解释: 4 皇后问题存在两个不同的解法。
解题思路:
* 采用三个数组分别记录每列、左对角线、右对角线是否有皇后
* 然后递归的遍历所有的坐标位置
package leetCode5_26;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author : caoguotao
* @date 创建时间:2019年5月31日 下午8:58:25
* @version 1.0
* @parameter
* @since
* @return
*/
public class Solution51 {
//列、左对角线、右对角线
boolean[] cols, diagLF, diagRT;
public static void main(String[] args) {
Solution51 s = new Solution51();
List<List<String>> lists = s.solveNQueens(4);
for (List<String> list : lists) {
for (String list2 : list) {
System.out.println(list2);
}
System.out.println("\n");
}
}
/**
* 解题思路:
* 采用三个数组分别记录每列、左对角线、右对角线是否有皇后
* 然后递归的遍历所有的左边位置
*/
public List<List<String>> solveNQueens(int n) {
cols = new boolean[n];
diagLF = new boolean[2 * n - 1];
diagRT = new boolean[2 * n - 1];
//保存所有的结果
List<List<String>> lists = new ArrayList<List<String>>();
if(n == 0) {
return lists;
}
//用来保存棋盘
char[][] boards = new char[n][n];
//初始化棋盘
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
boards[i][j] = '.';
}
}
DFS(0, 0, n, boards, lists);
return lists;
}
/**
*
* @param r 行号
* @param i 列号
* @param n 皇后总个数
* @param boards 棋盘
* @param lists 所有可能的棋盘
*/
public void DFS(int r, int c, int n, char[][] boards,
List<List<String>> lists) {
//得到一种可能
if(r == n) {
List<String> l = new ArrayList<String>();
for(int i = 0; i < n; i++) {
String s = "";
for(int j = 0; j < n; j++) {
s += boards[i][j];
}
l.add(s);
}
lists.add(l);
return;
}
for(int col = c; col < n; col++) {
//根据行、列计算所处的左对角线和右对角线的行数
if(cols[col] || diagLF[col + r] || diagRT[n - col + r - 1]) {
continue;
}
//放置皇后
boards[r][col]= 'Q';
//将对应位置的列、左对角线、右对角线修改为true
updateCLR(r, col, n, true);
DFS(r + 1 , 0, n, boards, lists);
//不放置皇后
boards[r][col] = '.';
updateCLR(r, col, n, false);
}
}
/**
*
* @param r 行号
* @param col 列号
* @param n 皇后数
* @param b 修改值
*/
public void updateCLR(int r, int col, int n, boolean b) {
cols[col] = b;
diagLF[col + r] = b;
diagRT[n - col + r - 1] = b;
}
}