leetcode--51. N 皇后
阿新 • • 發佈:2021-01-25
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);
}
}