n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
经典回溯算法
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
//todo:queue初始值为-1,若queue[i]不为-1,则在(i,queue[i])放置皇后
int[] queue = null;
List<List<String>> result = new ArrayList<List<String>>();
public List<List<String>> solveNQueens(int n) {
queue = new int[n];
Arrays.fill(queue, -1);
nQueue(0);
return result;
}
public void nQueue(int row) {
//todo:遍历col
for (int i = 0; i < queue.length; i++) {
//todo:if当前位置不被攻击
if(isAttack(row,i)){
//todo:放置棋子
queue[row] = i;
//todo:if满足row==N
if(row == queue.length-1){
//todo:得出结果
print();
}
//todo:else nQueue(row+1)
else
nQueue(row+1);
// todo:回溯,移除棋子row,col
queue[row] = -1;
}
}
}
public void print() {
List<String> temp = new ArrayList<>();
StringBuffer sb = new StringBuffer();
for(int i = 0;i<queue.length;i++){
for (int j = 0; j < queue.length; j++) {
if(queue[i] == j)
sb.append('Q');
else
sb.append('.');
}
temp.add(sb.toString());
sb.setLength(0);
}
result.add(temp);
}
//todo:若两旗子在相同对角线上则,行号-列号=常数或,行号+列号=常数
public boolean isAttack(int row, int col) {
int sum = row + col;
int difference = row - col;
if(queue[row] != -1)return false;
for (int i = 0; i < queue.length; i++) {
if(queue[i] == col) return false;
if(queue[i] != -1){
if(sum == (i+queue[i]) || difference == (i - queue[i])){
return false;
}
}
}
return true;
}
}