LeetCode/N皇后
阿新 • • 發佈:2022-05-10
n皇后問題研究的是如何將n個皇后放置在n×n的棋盤上並且使皇后彼此之間不能相互攻擊。
要求:任何兩個皇后不同行,不同列也不在同一條斜線上,
給你一個整數n,返回所有不同的n皇后問題的解決方案。
每一種解法包含一個不同的n皇后問題 的棋子放置方案,該方案中 'Q' 和 '.' 分別代表了皇后和空位
思路
使用回溯演算法,試探路徑,核心在於for迴圈裡面做遞迴,在遞迴呼叫之前做選擇,在遞迴之後撤銷選擇,具體回溯框架如下
def backtrack(路徑,選擇列表) if 滿足結束條件: result.add(路徑) return for 選擇 in 選擇列表: 做選擇 backtrack(路徑,選擇列表) 撤銷選擇
在N皇后問題中,回溯具體過程為,該行從任意一列中選擇一個棋子,判斷該路徑是否滿足要求,滿足要求繼續遞迴進入下一行,遞迴結束後撤銷上一步選擇,進行上一行其他列的選擇,每一次遞迴結束意為著到達邊界
點選檢視程式碼
class Solution { public: vector<vector<string>> res;//儲存最終結果 vector<vector<string>> solveNQueens(int n) { vector<string> board(n,string(n,'.'));//初始化棋盤,全為空 backtrack(board,0); return res; } //路徑:board中小於row的那些行都已經放置 //選擇列表:第row行所有列都可以作為選擇 //結束條件:row超過board最後一行 void backtrack(vector<string>& board,int row){ //觸發結束條件 if(row == board.size()){ res.push_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); //撤銷選擇 board[row][col]='.';//撤銷選擇是為了進入該行的下一個選擇 } } bool isValid(vector<string>& board,int row,int col){ int n = board[row].size(); //檢查列是否衝突 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; } };