leetcode51 52 N皇后
題目
n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。
上圖爲 8 皇后問題的一種解法。
給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。
每一種解法包含一個明確的 n 皇后問題的棋子放置方案,該方案中 ‘Q’ 和 ‘.’ 分別代表了皇后和空位。
示例:
輸入: 4
輸出: [
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],
["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解釋: 4 皇后問題存在兩個不同的解法。
回溯代碼模板
result = []
def backtrack(路徑, 選擇列表):
if 滿足結束條件:
result.add(路徑)
return
for 選擇 in 選擇列表:
做選擇
backtrack(路徑, 選擇列表)
撤銷選擇
代碼
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
vector<string> board(n, string(n, '.'));
backtrack(board, 0, res);
return res;
}
void backtrack(vector<string>& board, int row, vector<vector<string>>& res){
if(row==board.size()){
res.emplace_back(board);
return;
}
int n = board[row].size();
for(int col=0; col<n; ++col){
if(!isValid(board, row, col)){
continue;
}
board[row][col] = 'Q';
backtrack(board, row+1, res);
board[row][col] = '.';
}
}
bool isValid(vector<string>& board, int row, int col){
int n = board.size();
//檢查同列
for(int i=0; i<row; 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;
}
};
輸出解決方法的數量
class Solution {
public:
int res = 0;
int board[1000][1000];
int totalNQueens(int n) {
int N = n;
memset(board,0,sizeof(board));
Backtrace(0,board,N);
return res;
}
void Backtrace(int row,int board[][1000],int N){
if(row==N){
res++;
return;
}
for(int col = 0;col<N;col++){
if(!isValid(row,col,board,N)){
continue;
}
board[row][col]=1;
Backtrace(row+1,board,N);
board[row][col]=0;
}
}
bool isValid(int row,int col,int board[][1000],int N){
//檢查同列
for(int i=0; i<row; i++){
if(board[i][col]==1){
return false;
}
}
//右上
for(int i=row-1, j=col+1; i>=0 && j<N; i--, j++){
if(board[i][j]==1){
return false;
}
}
//左上
for(int i=row-1, j=col-1; i>=0 && j>=0; i--, j--){
if(board[i][j]==1){
return false;
}
}
return true;
}
};