@(labuladong的算法小抄)[回溯]
leetcode 51.N皇后
题目描述
解题思路
参考https://labuladong.gitbook.io/algo/di-ling-zhang-bi-du-xi-lie/hui-su-suan-fa-xiang-jie-xiu-ding-ban
回溯
class Solution {
public List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
//记录路径
char[][] track = new char[n][n];
//初始化空棋盘
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
track[i][j] = '.';
backtrack(track, 0);
return res;
}
/*
路径:小于row的所有行都已经存放在了track中
选择列表:每一行的所有列都是选择
结束条件:遍历完所有row,即track中已经存放了一张完整的满足条件的棋盘
*/
private void backtrack(char[][] track, int row) {
if (row == track.length) {
//将track转变成ArrayList<String>类型,添加进res中
res.add(charToArrayList(track));
return;
}
for (int col = 0; col < track.length; col++) {
//如果当前列不能放置皇后,则直接跳过
if (!isValid(track, row, col)) {
continue;
}
//做出选择
track[row][col] = 'Q';
backtrack(track, row + 1);
//撤销选择
track[row][col] = '.';
}
}
//将char[][]数组转变为ArrayList<String>
private List<String> charToArrayList(char[][] track) {
List<String> afterChange = new ArrayList<>();
for (char[] sub : track) {
//把sub包装成String类型存放到afterChange中
afterChange.add(String.valueOf(sub));
}
return afterChange;
}
//在当前棋盘track中,用于判断是否可以在[row,col]的位置放置皇后
private boolean isValid(char[][] track, int row, int col) {
boolean flag = true;
//检查列是否有皇后冲突
for (int i = row - 1; i >= 0; i--) {
if (track[i][col] == 'Q')
flag = false;
}
//检查左上方斜线是否有皇后冲突
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){
if (track[i][j] == 'Q')
flag = false;
}
//检查右上方斜线是否有皇后冲突
for (int i = row - 1, j = col + 1; i >=0 && j < track.length; i--, j++){
if (track[i][j] == 'Q')
flag = false;
}
return flag;
}
}