1. 程式人生 > >[Leetcode] n queens n皇後問題

[Leetcode] n queens n皇後問題

style false 皇後 size coder ack htm n皇後 color

The n-queens puzzle is the problem of placing n queens on an n×nchessboard such that no two queens attack each other.

技術分享

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens‘ placement, where‘Q‘and‘.‘both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

題意:返回皇後放置位置的所有解。

思路:采用回溯法,先試探的在第一行中的第一個位置放Q,然後去在二行中,在滿足條件下,放第二個Q,一次類推,若是有一行沒有地方放了,就放回上一行,改變此行Q的位置,依次類推,直到找到所有。

遇到問題一:如何記錄某一行中Q的位置?我們可以用一個數組記錄下某一行中Q所在的列數,這樣,我們就可以先記下Q的位置,然後去試探下一行中Q的位置,若最後不能成為解,需要回溯,則state置為-1(為負數就行),然後試探該行中其他位置是否滿足;

問題二:返回值中中間變量的定義形式?因為最後的結果是一個存放string類型的二維矩陣,所以定義中間變量時,可以用:vector<string> temp(n,string(n,‘.‘));

問題三:如何判斷一個位置是否合適放Q?因為,我們試探下一個Q時,是在下一行中進行的,所以,同行就自然排除了;所以只需判斷是否在同列,或者上一個Q的對角線上就行,對角線上的判斷可以用,列差的絕對值和行差的絕對值是否相等來判斷;

問題四:何時得出一種解?得出每行Q所在的列時,即row==n,數組中row應為僅能為n-1,若其等於n,說明已經找到該解中所有的Q位置。

代碼如下:

 1 class
Solution { 2 public: 3 vector<vector<string> > solveNQueens(int n) 4 { 5 vector<vector<string>> res; 6 vector<int> state(n,-1); 7 helper(state,0,res); 8 return res; 9 } 10 11 void helper(vector<int> &state,int row,vector<vector<string>> &res) 12 { 13 int n=state.size(); 14 if(row==n) 15 { 16 vector<string> temp(n,string(n,.)); 17 for(int i=0;i<n;++i) 18 { 19 temp[i][state[i]]=Q; 20 } 21 res.push_back(temp); 22 } 23 else 24 { 25 for(int col=0;col<n;++col) 26 { 27 if(isVaild(state,row,col)) 28 { 29 state[row]=col; 30 helper(state,row+1,res); 31 state[row]=-1; 32 } 33 } 34 } 35 } 36 37 bool isVaild(vector<int> &state,int row,int col) 38 { 39 for(int i=0;i<row;++i) 40 { 41 if(state[i]==col||abs(row-i)==abs(col-state[i])) 42 return false; 43 } 44 return true; 45 } 46 };

參考了JustDoIT的博客,其也給出了非遞歸的解法。

[Leetcode] n queens n皇後問題