问题描述:
解题思路:
1、先用一个二维数组chessboard表示棋盘,boolean数组colSetUsed表示有皇后的列
2、每次调用backtracing表示为一行添加皇后,在backtracing中为皇后选择放置皇后的列col位置,同时用一个全局变量colSetUsed表示之前行也就是之前的backtracing已经使用过的列的情况,方便剪枝。
3、用judgeLegal(row, i, n)判断当前位置(row,i)是否满足放置皇后的条件,主要用来判断左斜对角线以及右对角线是否满足,因为调用回溯,所以行不存在冲突的问题,而列冲突的问题在进入for循环时已经进行判断,所以只要判断斜对角线情况就可以了。
4、如果行row为n,则说明棋盘已经填充好,并且满足条件,可以将棋盘写入结果中。(回溯的终止条件)
具体代码:
class Solution {
LinkedList<List<String>> result = new LinkedList<>();
ArrayList<String> path = new ArrayList<>();
//棋盘的摆放情况
String[][] chessboard;
//用来存储已经存储过的列
boolean[] colSetUsed;
/**
public static void main(String[] args) {
System.out.println(new test().solveNQueens(4));
}
*/
public List<List<String>> solveNQueens(int n) {
chessboard = new String[n][n];
colSetUsed = new boolean[n];
int row = 0;
backtracing(row, n);
return result;
}
//用每次backtracing选择一个放置的列,行的选择则通过调用backtracing每次添加一行
public void backtracing(int row, int n) {
if (row == n) {
buildRowInPath(n);
result.add(new ArrayList<>(path));
path.clear();
return;
}
for (int i = 0; i < n; i++) {
if (colSetUsed[i]) {
continue;
}
//如果当前位置符合摆放皇后的规则
if (judgeLegal(row, i, n)) {
chessboard[row][i] = "Q";
colSetUsed[i] = true;
backtracing(row + 1, n);
colSetUsed[i] = false;
chessboard[row][i] = null;
}
}
}
//输入皇后所在的列,为path添加当前行的字符串布局“...Q...”
public void buildRowInPath(int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (chessboard[i][j] == null) {
sb.append(".");
} else {
sb.append("Q");
}
}
path.add(sb.toString());
sb.delete(0, sb.length());
}
}
//判断当前摆放位置的斜对角线上有没有皇后
public boolean judgeLegal(int row, int col, int n) {
int rowRecord = row - 1;
int colRecord = col - 1;
//判断左上角
while (rowRecord >= 0 && colRecord >= 0) {
if (chessboard[rowRecord][colRecord] != null && chessboard[rowRecord][colRecord].equals("Q")) {
return false;
}
rowRecord--;
colRecord--;
}
//判断右上角
rowRecord = row - 1;
colRecord = col + 1;
//判断左上角
while (rowRecord >= 0 && colRecord < n) {
if (chessboard[rowRecord][colRecord] != null && chessboard[rowRecord][colRecord].equals("Q")) {
return false;
}
rowRecord--;
colRecord++;
}
return true;
}
}