n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
输入:n = 4
输出:[[".Q…","…Q",“Q…”,"…Q."],["…Q.",“Q…”,"…Q",".Q…"]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[[“Q”]]
提示:
1 <= n <= 9
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
下面代码不能通过,不知道为什么不能输出正确结果
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/*
String类不可改变
*/
public class Main {
Vector<Vector<StringBuffer>> res=new Vector<>();
public Vector<Vector<StringBuffer>> permute(int nums){
int len=nums;
Vector<StringBuffer> board = new Vector<>();
for(int i=0;i<len;i++){
board.add(getString(len));
}
//如果为0返回空数组
if(len==0){
return res;
}
dfs(0,board);
System.out.println("结果"+res);
return res;
}
public static StringBuffer getString(int len){
StringBuffer stringBuffer=new StringBuffer();
String str ="";
for(int j=0;j<len;j++){
str+='.';
}
stringBuffer.append(str);
return stringBuffer;
}
public void dfs(int row,Vector<StringBuffer> boa) {
if(row==boa.size()){
res.add(new Vector<StringBuffer>(boa));
System.out.println("输出"+boa);
return;
}
int n=boa.elementAt(row).length();
for(int col=0;col<n;col++){
if(isValid(boa,row,col)){
boa.elementAt(row).replace(col,col+1,"Q");
//进入下一层深度优先遍历
dfs(row+1,boa);
//还原回未访问的状态,防止影响下一个for循环
boa.elementAt(row).replace(col,col+1,".");
}
}
}
/* 是否可以在 board[row][col] 放置皇后? */
public static boolean isValid(Vector<StringBuffer> board, int row, int col) {
int n = board.size();
// 检查列是否有皇后互相冲突
for (int i = 0; i < n; i++) {
if (board.elementAt(i).charAt(col) == 'Q')
return false;
}
// 检查右上方是否有皇后互相冲突
for (int i = row - 1, j = col + 1;
i >= 0 && j < n; i--, j++) {
if (board.elementAt(i).charAt(j) == 'Q')
return false;
}
// 检查左上方是否有皇后互相冲突
for (int i = row - 1, j = col - 1;
i >= 0 && j >= 0; i--, j--) {
if (board.elementAt(i).charAt(j) == 'Q')
return false;
}
return true;
}
public static void main(String[] args) {
int nums =4;
Main solution = new Main();
Vector<Vector<StringBuffer>> lists = solution.permute(nums);
System.out.println(lists);
}
}
另附能通过的参考代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
class Main {
List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] board = new char[n][n];
for (char[] i : board){
Arrays.fill(i,'.');
}
backtrack(board,0);
return res;
}
// 路径:board 中小于 row 的那些行都已经成功放置了皇后
// 选择列表:第 row 行的所有列都是放置皇后的选择
// 结束条件:row 超过 board 的最后一行
void backtrack(char[][] board, int row){
if (row == board.length){
res.add(array2List(board));
return;
}
for (int j = 0;j<board.length;j++){
if (!check(board,row,j)){
continue;
}
board[row][j] = 'Q';
backtrack(board,row+1);
board[row][j] = '.';
}
}
List<String> array2List(char[][] board){
List<String> res = new LinkedList<>();
for (char[] i : board){
StringBuffer sb = new StringBuffer();
for (char j : i){
sb.append(j);
}
res.add(sb.toString());
}
return res;
}
boolean check(char[][] board,int row,int col){
int n = board.length;
// 检查列是否有皇后互相冲突
for (int i = 0; i < n; i++) {
if (board[i][col] == 'Q')
return false;
}
// 检查右上方是否有皇后互相冲突
for (int i = row - 1, j = col + 1;
i >= 0 && j < n; i--, j++) {
if (board[i][j] == 'Q')
return false;
}
// 检查左上方是否有皇后互相冲突
for (int i = row - 1, j = col - 1;
i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 'Q')
return false;
}
return true;
}
public static void main(String[] args) {
int nums =4;
Main solution = new Main();
List<List<String>> lists = solution.solveNQueens(nums);
System.out.println(lists);
}
}