33. N皇后问题
33. N皇后问题
n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。
给定一个整数n,返回所有不同的n皇后问题的解决方案。
每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。
样例
对于4皇后问题存在两种解决的方案:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
思路:
解法1:一个全排列的问题,见《剑指offer》,只需要把排列后的数列转换为题目要求的字符串格式返回就好了。这种方法比较慢,主要是由于生成一个全排列的时间复杂度太大,在生成全排列的过程中对于一些错误的解不能及时地剔除,导致算法比较耗时。
1 class Solution { 2 public: 3 /* 4 * @param n: The number of queens 5 * @return: All distinct solutions 6 */ 7 void swap(int &a, int &b) 8 { 9 int c=a; 10 a=b; 11 b=c; 12 } 13 bool isOk(vector<int> &arr)//检查两个皇后是否在同一对角线上 14 { 15 for(int i=0; i<arr.size(); ++i) 16 { 17 for(int j=i+1; j<arr.size(); ++j) 18 { 19 if(i-j==arr[i]-arr[j] || j-i==arr[i]-arr[j])return false; 20 } 21 } 22 return true; 23 } 24 void Backtrace(vector<int> &arr, int i, vector<vector<int> > &result)//全排列 25 { 26 if(i==arr.size()){ 27 if(isOk(arr))result.push_back(arr); 28 }else{ 29 for(int j=i; j<arr.size(); ++j) 30 { 31 swap(arr[i], arr[j]); 32 Backtrace(arr, i+1, result); 33 swap(arr[i], arr[j]); 34 } 35 } 36 } 37 void int2str(vector<vector<int> > &result, vector<vector<string> > &final, int n)//转化为题目要求的格式 38 { 39 for(int i=0; i<result.size(); ++i) 40 { 41 string str(n, '.'); 42 vector<string> tmp(n, str); 43 for(int idx=0; idx<result[i].size(); ++idx) 44 { 45 tmp[idx][result[i][idx]]='Q'; 46 } 47 final.push_back(tmp); 48 } 49 } 50 vector<vector<string>> solveNQueens(int n) { 51 vector<int> arr(n, 0); 52 for(int i=0; i<n; ++i)arr[i]=i; 53 vector<vector<int> > result; 54 Backtrace(arr, 0, result); 55 vector<vector<string> > final; 56 int2str(result, final, n); 57 return final; 58 } 59 };
解法2:回溯法。在回溯的过程中及时剔除一些不能得到正确结果的分支,可大大降低时间复杂度。
参考:https://blog.csdn.net/hackbuteer1/article/details/6657109
1 class Solution { 2 public: 3 /* 4 * @param n: The number of queens 5 * @return: All distinct solutions 6 */ 7 void int2str(vector<vector<int> > &result, vector<vector<string> > &final, int n)//转化为题目要求的格式 8 { 9 for(int i=0; i<result.size(); ++i) 10 { 11 string str(n, '.'); 12 vector<string> tmp(n, str); 13 for(int idx=0; idx<result[i].size(); ++idx) 14 { 15 tmp[idx][result[i][idx]]='Q'; 16 } 17 final.push_back(tmp); 18 } 19 } 20 int abs(int a, int b) 21 { 22 if(a>b)return a-b; 23 else return b-a; 24 } 25 bool isOk(vector<int> &arr, int i, int j)//判断是否有行列和对角线冲突 26 { 27 for(int idx=0; idx<i; ++idx) 28 { 29 if(arr[idx]==j || abs(idx, i)==abs(arr[idx], j))return false; 30 } 31 return true; 32 } 33 vector<vector<string>> solveNQueens(int n) { 34 if(n<=0)return vector<vector<string> > (); 35 vector<vector<int> > result; 36 vector<int> arr(n, -1); 37 int i=0, j=0; 38 while(i<n) 39 { 40 while(j<n) 41 { 42 if(isOk(arr, i, j)) 43 { 44 arr[i]=j; 45 j=0; 46 break; 47 } 48 ++j; 49 } 50 if(arr[i]==-1) 51 { 52 if(i==0)break; 53 --i; 54 j=arr[i]+1; 55 arr[i]=-1; 56 continue; 57 } 58 if(i==n-1) 59 { 60 result.push_back(arr); 61 j=arr[i]+1; 62 arr[i]=-1; 63 continue; 64 } 65 ++i; 66 } 67 vector<vector<string> > final; 68 int2str(result, final, n); 69 return final; 70 } 71 };

浙公网安备 33010602011771号