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 };

 

 

 

 

posted @ 2018-05-21 18:10  jeysin  阅读(215)  评论(0)    收藏  举报