现在的位置: 首页 > 综合 > 正文

LeetCode题解:N-Queens I and II

2014年01月19日 ⁄ 综合 ⁄ 共 1824字 ⁄ 字号 评论关闭

N-Queens

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

N-Queens II

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

思路:

经典的n皇后问题,可以参考任何一本算法书。一般是通过回溯法求解。这里给出一个没有专门优化过的解法。

事实上我考虑过这个问题,因为棋盘的对称性,应该可以有更好的基于群论的求解方法。这个就要咨询数学家了。

第二题只要消去具体的转化,只计算解的个数即可。当然希望性能更好一些。

题解:

class Solution {
public:
    vector<vector<string>> solution;
    
    void generate_solution(const vector<int>& queen)
    {
        vector<string> s;
        for(int i = 0; i < queen.size(); ++i)
        {
            string l(queen.size(), '.');
            l[queen[i]] = 'Q';
            s.emplace_back(move(l));     // avoid copy!
        }
        solution.emplace_back(move(s));
    }
    
    void traverse_solution_space(vector<int>& queen, int placed, int total)
    {
        if (placed == total)
        {
            generate_solution(queen);    
            return;
        }
        
        // try place the queens
        for(int i = 0; i < queen.size(); ++i)
        {
            bool valid = true;
            // verify the position
            for(int j = 0; j < placed; ++j)
            {
                if (i == queen[j] ||  // same column
                    abs(queen[j] - i) == placed - j) // diagonal attack
                {
                    valid = false;
                    break;
                }
            }
            
            if (valid)
            {
                queen[placed] = i;
                traverse_solution_space(queen, placed + 1, total);
            }
        }
    }

    vector<vector<string> > solveNQueens(int n) {
        solution.clear();
        vector<int> queen(n);
        
        traverse_solution_space(queen, 0, n);
        
        return solution;
    }
};


class Solution {
public:
    vector<int> board;
    vector<int> avail;
    
    int valid_solutions;
    
    void traverse_solution_space(int k, int n)
    {
        if (k == n)
        {
            ++valid_solutions;
            return;
        }
        
        for(int i = 0; i < n; ++i)
            if (avail[i] == 0)
            {
                bool iok = true;
                for(int j = 0; j < k; ++j)
                    if (abs(board[j] - i) == k - j)
                    {
                        iok = false;
                        break;
                    }
                if (iok)
                {
                    avail[i] = 1;
                    board[k] = i;
                    traverse_solution_space(k + 1, n);
                    avail[i] = 0;
                }
            }
    }
    
    int totalNQueens(int n) 
    {
        valid_solutions = 0;
        
        board.resize(n);
        avail.resize(n);
        
        fill(begin(avail), end(avail), 0);
        
        traverse_solution_space(0, n);
        
        return valid_solutions;
    }
};

抱歉!评论已关闭.