LeetCode 51. N-Queens和52. N-Queens II的位运算解法

最近在刷Leetcode,遇到了N皇后的问题。去网上搜了下,发现了一个用位运算求解可行解个数的非常简单的方法(点击这里查看)。博主在里面添加了非常详细的注释和解释,只要仔细研究一下,相信每个人都能看懂。

LeetCode 52题只要求输出可行解的个数,用上面博主的代码便可轻松通过。52题的AC代码如下:(注释已删除,可查看上面博主的注释)

class Solution {
public:
    int totalNQueens(int n) {
        limit = (1 << n) - 1;
        return nQueens(0, 0, 0);
    }
    
private:
    int nQueens(int res, int ld, int rd)
    {
        if (res != limit)
        {
            int pos = limit & ~(res | ld | rd);
            int result = 0;
            while (pos)
            {
                int p = pos & -pos;
                pos -= p;
                result += nQueens(res + p, (ld + p) << 1, (rd + p) >> 1);
            }
            return result;
        }
        return 1;
    }
    
    int limit;
};

但是51题需要求出所有的可行解,看了很多博客好像都是用普通的枚举+约束来做的(这篇博客的约束函数写得非常简单易懂,可以看一下),但是没有看到用位运算来解决的。于是尝试着改了一下上面的代码,发现只需要做很小的变动就可以了。51题的AC代码如下:

class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        limit = (1 << n) - 1;
        vector<string> vec(n, string(n, '.'));// 初始化一个全是'.'的vector,用来保存尝试结果
        nQueue(0, 0, 0, 0, vec);// 参数k初始化为0,表示第0行
        return result;
    }
    
private:
    // 第4个参数k表示尝试的行数
    void nQueue(long res, long ld, long rd, int k, vector<string>& vec)
    {
        if (res != limit)
        {
            int pos = limit & ~(res | ld | rd);
            while (pos)
            {
                int p = pos & -pos;
                pos -= p;
                /**
                 * pos = 2^t0 + 2^t1 + 2^t2 + ... (t0 < t1 < t2 < ...)
                 * 则p = 2^t0,log2(p) = t0
                 * t0则为可放置皇后的列
                 */
                vec[k][log2(p)] = 'Q';// 在第k行第t0列尝试放置一个皇后
                nQueue(res + p, (ld + p) << 1, (rd + p) >> 1, k + 1, vec);// k + 1 : 继续进行下一行的尝试
                vec[k][log2(p)] = '.';// 因为参数是引用,所以此处要复原vec
            }
        }
        else result.push_back(vec);// 找到一个解,添加到结果中
    }

    vector<vector<string>> result;
    int limit;
};

位运算的代码提交后,Run Time只用了3ms,试了下其他的方法,都在15ms左右,速度确实提高了很多。如果大家有更好的方法,欢迎交流~

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页