回溯 皇后 演算法筆記 回溯演算法 N皇后問題

2021-10-13 23:32:06 字數 3053 閱讀 5457

❞n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。

上圖為 8 皇后問題的一種解法。

給定乙個整數 n,返回所有不同的 n 皇后問題的解決方案。

每一種解法包含乙個明確的 n 皇后問題的棋子放置方案,該方案中 'q' 和 '.' 分別代表了皇后和空位。

示例: 輸入: 4

輸出: [

[".q..",  // 解法 1

"...q",

"q...",

"..q."],

["..q.",  // 解法 2

"q...",

"...q",

".q.."]

]解釋: 4 皇后問題存在兩個不同的解法。

都知道n皇后問題是回溯演算法解決的經典問題,但是用回溯解決多了組合、切割、子集、排列問題之後,遇到這種二位矩陣還會有點不知所措。

首先來看一下皇后們的約束條件:

不能同行

不能同列

不能同斜線

確定完約束條件,來看看究竟要怎麼去搜尋皇后們的位置,其實搜尋皇后的位置,可以抽象為一棵樹。

下面我用乙個3 * 3 的棋牌,將搜尋過程抽象為一顆樹,如圖:

從圖中,可以看出,二維矩陣中矩陣的高就是這顆樹的高度,矩陣的寬就是樹型結構中每乙個節點的寬度。

那麼我們用皇后們的約束條件,來回溯搜尋這顆樹,「只要搜尋到了樹的葉子節點,說明就找到了皇后們的合理位置了」

按照我總結的如下回溯模板,我們來依次分析:

void backtracking(引數) 

for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小)) 

}

我依然是定義全域性變數二維陣列result來記錄最終結果。

引數n是棋牌的大小,然後用row來記錄當前遍歷到棋盤的第幾層了。

**如下:

vector> result;

void backtracking(int n, int row, vector& chessboard) 

遞迴深度就是row控制棋盤的行,每一層裡for迴圈的col控制棋盤的列,一行一列,確定了放置皇后的位置。每次都是要從新的一行的起始位置開始搜,所以都是從0開始。

**如下:

for (int col = 0; col     if (isvalid(row, col, chessboard, n)) 

}

按照如下標準去重:

不能同行

不能同列

不能同斜線 (45度和135度角)

**如下:

bool isvalid(int row, int col, vector& chessboard, int n) 

}// 檢查 45度角是否有皇后for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) 

}// 檢查 135度角是否有皇后for(int i = row - 1, j = col + 1; i >= 0 && j         if (chessboard[i][j] == 'q') 

}return true;

}

在這份**中,細心的同學可以發現為什麼沒有在同行進行檢查呢?

因為在單層搜尋的過程中,每一層遞迴,只會選for迴圈(也就是同一行)裡的乙個元素,所以不用去重了。

那麼按照這個模板不難寫出如下**:

class solution for (int col = 0; col         if (isvalid(row, col, chessboard, n)) }}

bool isvalid(int row, int col, vector& chessboard, int n) 

}// 檢查 45度角是否有皇后for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) 

}// 檢查 135度角是否有皇后for(int i = row - 1, j = col + 1; i >= 0 && j         if (chessboard[i][j] == 'q') 

}return true;

}public:

vector> solvenqueens(int n) 

};

可以看出,除了驗證棋盤合法性的**,省下來部分就是按照回溯法模板來的。

本題是我們解決棋盤問題的第一道題目。

如果從來沒有接觸過n皇后問題的同學看著這樣的題會感覺無從下手,可能知道要用回溯法,但也不知道該怎麼去搜。

「這裡我明確給出了棋盤的寬度就是for迴圈的長度,遞迴的深度就是棋盤的高度,這樣就可以套進回溯法的模板裡了」

大家可以在仔細體會體會!

就醬,如果感覺「**隨想錄」乾貨滿滿,就分享給身邊的朋友同學吧,他們可能也需要!

打算從頭開始打卡的錄友,可以在「演算法彙總」這裡找到歷史文章,很多錄友都在從頭打卡,你並不孤單!

-------end-------

趕緊給「**隨想錄」加乙個星標吧,方便第一時間閱讀文章「**隨想錄」期待你的關注!

每天8:35準時推送一道經典演算法題目,推送的每道題目都不是孤立的,而是由淺入深,環環相扣,幫你梳理演算法知識脈絡,輕鬆學演算法!

N皇后 回溯演算法

res 用於儲存最終結果 defdfs n,x,arr,cols,diag1,diag2 if x n else 對於每一行x,迴圈搜尋不同的列y值 for y in range n if check x,y 合法 更新合法性判斷引數 更新arr,cols,diag1,diag2等引數 dfs n,...

回溯演算法n皇后問題

這是一道考查應聘者綜合能力的問題,其中包含了演算法的設計 ui的設計 介面的設計等問題,當然在具體面試中沒有時間讓應聘者完成整個設計和編碼,但是面試官往往通過了解應聘者的設計思路和工作步驟來考查應聘者的能力。本節將具體分析這道程式設計題。所涉及到的知識點 回溯演算法 net桌面應用程式的ui設計 分...

n皇后問題(回溯演算法)

問題定義 西洋棋中,皇后可以直線進攻也可以斜線進攻,問在nxn的西洋棋棋盤上擺n個皇后,問擺使得n個皇后之間無法相互進攻有多少種擺法?通過回溯法解決。def isvalid matrix,row,col n len matrix for i in range row for j in range n...