首页 > 代码库 > 【LeetCode】N-Queens

【LeetCode】N-Queens

N-Queens

The n-queens puzzle is the problem of placing n queens on an n×n chessboard 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.."]]

 

这题和Sudoku Solver是一个套路,回溯法尝试所有可能性,将可行解的保存起来。可以对比着看。

我们先用vector<int>来存放可行解,下标代表行号,元素代表列号。

因此上图中Solution 1用vector<int>表示就是[1,3,0,2]

解题流程就是在下一行中尝试列数(0~n-1),如果可行则递归下去,如果不可行则弹出继续尝试下一列。

代码中加入了大量注释,还是很好理解的。

class Solution {public:    vector<vector<string> > solveNQueens(int n)     {        vector<vector<int> > result;    //全局变量        vector<int> cur;                //递归栈中的变量        solve(result, cur, n);            //符合条件的cur加入result        return transfer(result, n);        //vector<int>转为vector<string>    }    void solve(vector<vector<int> > &result, vector<int> cur, int n)    {        if(cur.size() == n)        {//找到解            result.push_back(cur);        }        else        {            for(int i = 0; i < n; i ++)            {//尝试所有可能                cur.push_back(i);                if(isValid(cur))                {//可行则递归下去                    solve(result, cur, n);                }                cur.pop_back();            }        }    }    vector<vector<string> > transfer(vector<vector<int> > &result, int n)    {        vector<vector<string> > ret;        for(vector<vector<int> >::size_type st1 = 0; st1 < result.size(); st1 ++)        {//第st1个解            vector<string> cur(n, string(n,.));            for(vector<int>::size_type st2 = 0; st2 < n; st2 ++)            {//第st2行                cur[st2][result[st1][st2]] = Q;            }            ret.push_back(cur);        }        return ret;    }    bool isValid(vector<int> &cur)    {//针对新加点进行验证        int sz = cur.size();        int row = sz-1;            //新加点的行数sz-1        int col = cur[sz-1];    //列数cur[sz-1]        for(vector<int>::size_type st = 0; st < sz-1; st ++)        {    //验证同列错误(由于数组下标不同,同行错误不存在)            if(col == cur[st])                return false;            //验证同对角线错误            if(fabs((double)row-st)==fabs((double)col-cur[st]))                return false;        }        return true;    }};

 

【LeetCode】N-Queens