1. 程式人生 > 其它 >LeetCode面試題 08.12. 八皇后---回溯演算法解決N皇后問題(C++實現)

LeetCode面試題 08.12. 八皇后---回溯演算法解決N皇后問題(C++實現)

N皇后問題源於著名的八皇后問題:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法!

將8x8擴充套件為NxN即為N皇后問題,要解決此問題,最簡單的方法就是暴力列舉,此時的時間複雜度為N^2,回溯演算法與簡單暴力列舉類似,不同點在於當判定某種狀態不符合答案時,便不再繼續列舉此狀態的後續狀態,而是回溯到該狀態之前,繼續遍歷其他的可能值。

 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 using namespace
std; 5 6 bool check(const vector<vector<int>> &vec, int row, int col, int n) 7 { 8 // 檢查列衝突 9 for (int i = 0; i < n; i++) 10 { 11 if (vec[i][col] == 1) 12 return false; 13 } 14 15 // 檢查左上對角線 16 for (int i = row - 1, j = col - 1; i >= 0
&& j >= 0; i--, j--) 17 { 18 if (vec[i][j] == 1) 19 return false; 20 } 21 for (int i = row + 1, j = col + 1; i < n &&j < n; i++, j++) 22 { 23 if (vec[i][j] == 1) 24 return false; 25 } 26 27 // 檢查左下對角線 28 for (int
i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) 29 { 30 if (vec[i][j] == 1) 31 return false; 32 } 33 for (int i = row + 1, j = col - 1; i < n&&j >= 0; i++, j--) 34 { 35 if (vec[i][j] == 1) 36 return false; 37 } 38 39 return true; 40 } 41 42 void findQueen(vector<vector<int>> &vec, int row, int n, vector<vector<string>> &res) 43 { 44 if (row == n) 45 { 46 vector<string> queenResult; 47 for (auto &i : vec) 48 { 49 string str; 50 for (auto j : i) 51 { 52 if (j == 1) 53 str += 'O'; 54 else 55 str += '+'; 56 } 57 queenResult.push_back(str); 58 } 59 res.push_back(queenResult); 60 } 61 62 for (int col = 0; col < n; col++) 63 { 64 // 回溯 65 if (check(vec, row, col, n)) 66 { 67 vec[row][col] = 1; 68 findQueen(vec, row + 1, n, res); 69 vec[row][col] = 0; // 遍歷下一列時,將當前列重置 70 } 71 } 72 } 73 74 // N皇后 75 vector<vector<string>> NQueen(int n) 76 { 77 vector<vector<int>> vec(n, vector<int>(n, 0)); 78 vector<vector<string>> res; 79 findQueen(vec, 0, n, res); 80 return res; 81 } 82 83 int main() 84 { 85 auto res = NQueen(8); 86 for (int i = 0; i < res.size(); i++) 87 { 88 cout << "result " << i << ":" << endl; 89 for (auto &s : res[i]) 90 cout << s << endl; 91 } 92 return 0; 93 }