placeQueens函数用回溯法求解八皇后问题,核心是用三个布尔数组O(1)判断列、主对角线(row-col+n-1)、副对角线(row+col)冲突;递归到底时需深拷贝board保存解,避免引用错误;LeetCode 51题返回所有解,52题仅计数。

用回溯法写 placeQueens 函数最直接
八皇后问题本质是搜索所有合法的皇后摆放组合,回溯是最自然的解法。核心在于:每放一个皇后,就检查它是否与之前所有皇后冲突;不冲突就继续下一行,冲突就回退。
关键点不是“怎么写循环”,而是“怎么高效判断冲突”。别用暴力遍历已放皇后——用三个布尔数组分别记录列、主对角线(row - col)、副对角线(row + col)是否已被占用,O(1) 判断。
-
cols[j]表示第j列是否有皇后 -
diag1[row - col + n - 1]防止row - col为负,加偏移量映射到非负索引(长度2n-1) -
diag2[row + col]范围是0到2n-2,长度也是2n-1
递归终止条件和路径记录别漏掉 board 拷贝
当 row == n 时说明已成功放下 n 个皇后,此时要保存当前解。常见错误是直接 push board 的引用或指针,结果后续递归修改导致所有解变成同一份终态。
必须做深拷贝:
立即学习“C++免费学习笔记(深入)”;
vector<string> solution = board; solutions.push_back(solution);
如果用 vector<vector>></vector> 存棋盘,也要逐行复制。别依赖 std::move——回溯过程中还要继续用原 board 回退。
输出格式按题目要求选 vector<vector>></vector> 还是计数
LeetCode 第 51 题返回所有解,类型是 vector<vector>></vector>;第 52 题只要数量,返回 int。二者主逻辑一致,差异只在递归终点:
- 需要全部解:每次到达终点都存一份
board - 只计数:终点时
count++,全程不存中间状态,内存开销小得多 - 若用
string表示每行(如"Q...."),注意构造时用string(n, '.')初始化再改某位为'Q',别手写重复字符
std::vector 初始化大小和对角线索引易越界
两个典型坑:
- 声明
diag1和diag2时写成vector<bool>(n)</bool>——错!长度必须是2 * n - 1,否则访问diag1[n]直接越界 - 主对角线索引
row - col最小为-(n-1),所以偏移量得是n - 1,写成n或2*n都会导致部分位置永远无法命中 - 调试时可加断言:
assert(row - col + n - 1
边界值永远值得多看一眼,尤其涉及二维映射到一维时。


















