n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4 输出: 2 解释: 4 皇后问题存在如下两个不同的解法。 [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ]
* 解题思路:
* 采用三个数组分别记录每列、左对角线、右对角线是否有皇后
* 然后递归的遍历所有的左边位置
package leetCode5_26;
import java.util.ArrayList;
import java.util.List;
/**
* @author : caoguotao
* @date 创建时间:2019年5月31日 下午10:09:03
* @version 1.0
* @parameter
* @since
* @return
*/
public class Solution52 {
// 列、左对角线、右对角线
boolean[] cols, diagLF, diagRT;
public static void main(String[] args) {
Solution52 s = new Solution52();
int res = s.totalNQueens(4);
System.out.println(res);
}
/**
* 解题思路:
* 采用三个数组分别记录每列、左对角线、右对角线是否有皇后
* 然后递归的遍历所有的左边位置
*/
public int totalNQueens(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 0;
}
// 用来保存棋盘
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.size();
}
/**
*
* @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;
}
}