[Leetcode] n queens n皇后问题

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是否满足条件;因为行数没法取到当前行,所以只需判断是否在同列,或者之前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的博客,其也给出了非递归的解法。

posted @ 2017-07-08 16:44  王大咩的图书馆  阅读(307)  评论(0编辑  收藏  举报