LeetCode位运算处理八皇后问题

tech2025-02-04  11

[1]位运算处理八皇后问题LeetCode

总体思路具体实现 题目链接:https://leetcode-cn.com/problems/n-queens/

总体思路

首先用到了一个int(姑且称之为伪数组)来存储可放置的位置,自然有其好处,省去了繁杂的创建数组的过程,并且便于用位运算进行顺次约束。分为三个约束条件,姑且用line,knife以及fork代替,分别用于,列约束,左斜约束,右斜约束(擅自命名,顺便帮自己记下“左手拿叉,右手拿刀”。 八皇后离不开深度优先搜索,为了思路更加清晰,将生成输出部分抽象为一个generateBoard函数,将生成可行解的部分抽象为一个solve函数,并且用solveNQueen连接两者。 每次深度搜索时,先判断是否为零,若为零,则意味着此时可以终止深度搜索。若不为零,则取得位数最低的一个零1进行下一步的深度搜索,回溯时将其置1,避免死循环。 生成部分,首先全部置’.’,然后根据solutions将放置皇后处置’Q’。 用到了高效率位运算: •int __builtin_ctz (unsigned int x) 返回x的二进制下末尾的0的个数

具体实现

class Solution { public: vector<vector<string>> solveNQueens(int n) { auto solutions = vector<vector<string>>(); auto queens = vector<int>(n, -1); solve(solutions, queens, n, 0, 0, 0, 0); return solutions; } void solve(vector<vector<string>> &solutions, vector<int> &queens, int n, int row, int line, int knife, int fork) { if (row == n) { auto board = generateBoard(queens, n); solutions.push_back(board); } else { int availablePositions = ((1 << n) - 1) & (~(line | knife | fork)); int & ap=availablePositions; while (ap != 0) { int position = ap & (-ap); ap = ap & (ap - 1); int column = __builtin_ctz(position); queens[row] = column; solve(solutions, queens, n, row + 1, line | position, (knife | position) >> 1, (fork | position) << 1); queens[row] = -1; } } } vector<string> generateBoard(vector<int> &queens, int n) { auto board = vector<string>(); for (int i = 0; i < n; i++) { string row = string(n, '.'); row[queens[i]] = 'Q'; board.push_back(row); } return board; } };
最新回复(0)