前言
什么是皇后
- 就是一个排列程序
- 0~N行,每一行选取一个列,每个列不能重复(解决皇后行列之间攻击问题)
- 在上面基础上,在限制上对角线不可以重复。其实就是排列加上了限制条件。
题目细节
对角线是什么,如何判断对角线是否会攻击到呢,也就是如何判断对角线的限制条件
关于 \ 对角线
- 这条对角线的,行号减列号是相等的,也就是x-y是相等的。
-
关于 / 对角线
这条对角线的,行号加列号是相等的,也就是x+y是相等的。
-
�代码实现,完整注释
class Solution {//存一下数字n,省着下传了private int n;//记录一个列号是否用过private Map<Integer,Boolean> columnUsed = new HashMap<>();//记录一个左\对角线的值是否用过.row - colprivate Map<Integer,Boolean> leftDiagonalUsed = new HashMap<>();//记录一个右/对角线的值是否用过 row + colprivate Map<Integer,Boolean> rightDiagonalUsed = new HashMap<>();//记录当前的选择列private List<Integer> chosen = new ArrayList<>();//我们的最终要返回的答案,未格式化版本private List<List<Integer>> answer = new ArrayList<>();public List<List<String>> solveNQueens(int n) {//保存nthis.n = n;//执行DFSdfs(0);//格式化的resultList<List<String>> result = new ArrayList<>();//这一层循环,每一次循环代表的是一个棋牌的摆放方式for(List<Integer> oneAnswer : answer){//这一次循环代表的是,一个棋盘的一行的Q的位置List<String> oneResult = new ArrayList<>();for(Integer qIndex : oneAnswer){//首先用一个char数组表示一行,然后全填满.char[] row = new char[n];Arrays.fill(row, '.');row[qIndex] = 'Q';String oneRowResult = new String(row);oneResult.add(oneRowResult);}result.add(oneResult);}return result;}public void dfs(Integer row){//递归终止条件。当0~(n-1)行都放完了,到n了就终止了if(row == n){answer.add(new ArrayList<>(chosen));return;}//写核心逻辑,在一行中,考虑所有列,放在那一列上。//也就是在0~(n-1)列中选一列没有用过的for(int column = 0; column < n; column++){//如果:1.这一列没有被用过 2.左右对角线都是可以使用的if(!columnUsed.getOrDefault(column,false) && !leftDiagonalUsed.getOrDefault(row - column,false) && !rightDiagonalUsed.getOrDefault(row + column,false)){//使用当前列,放入选择chosen.add(column);//记录该列为已使用columnUsed.put(column,true);//记录当前左右对角线为已使用。leftDiagonalUsed.put(row - column,true);rightDiagonalUsed.put(row + column,true);//这一行已经放完了,去放下一行dfs(row +1);//都放完了要还原现场。回溯!//设置列使用为false,变为没使用过columnUsed.put(column,false);//设置左右对角线未使用leftDiagonalUsed.put(row - column,false);rightDiagonalUsed.put(row + column,false);//当前选择里把放在末尾的这一列去掉chosen.remove(chosen.size()-1);}}}}
