[LeetCode] 51. N-Queens N皇后问题
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.
Example:
Input: 4
Output: [
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."], ["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
经典的N皇后问题,基本所有的算法书中都会包含的问题。可能有些人对国际象棋不太熟悉,大家都知道中国象棋中最叼的是车,横竖都能走,但是在国际象棋中还有更叼的,就是皇后,不但能横竖走,还能走两个斜线,有如 bug 一般的存在。所以经典的八皇后问题就应运而生了,在一个 8x8 大小的棋盘上如果才能放8个皇后,使得两两之间不能相遇,所谓一山不能容二虎,而这里有八个母老虎,互相都不能相遇。对于这类问题,没有太简便的方法,只能使用穷举法,就是尝试所有的组合,每放置一个新的皇后的时候,必须要保证跟之前的所有皇后不能冲突,若发生了冲突,说明当前位置不能放,要重新找地方,这个逻辑非常适合用递归来做。我们先建立一个长度为 nxn 的全是点的数组 queens,然后从第0行开始调用递归。在递归函数中,我们首先判断当前行数是否已经为n,是的话,说明所有的皇后都已经成功放置好了,所以我们只要将 queens 数组加入结果 res 中即可。否则的话,我们遍历该行的所有列的位置,行跟列的位置都确定后,我们要验证当前位置是否会产生冲突,那么就需要使用一个子函数来判断了,首先验证该列是否有冲突,就遍历之前的所有行,若某一行相同列也有皇后,则冲突返回false;再验证两个对角线是否冲突,就是一些坐标转换,主要不要写错了,若都没有冲突,则说明该位置可以放皇后,放了新皇后之后,再对下一行调用递归即可,注意递归结束之后要返回状态,参见代码如下:
解法一:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
vector<string> queens(n, string(n, '.'));
helper(, queens, res);
return res;
}
void helper(int curRow, vector<string>& queens, vector<vector<string>>& res) {
int n = queens.size();
if (curRow == n) {
res.push_back(queens);
return;
}
for (int i = ; i < n; ++i) {
if (isValid(queens, curRow, i)) {
queens[curRow][i] = 'Q';
helper(curRow + , queens, res);
queens[curRow][i] = '.';
}
}
}
bool isValid(vector<string>& queens, int row, int col) {
for (int i = ; i < row; ++i) {
if (queens[i][col] == 'Q') return false;
}
for (int i = row - , j = col - ; i >= && j >= ; --i, --j) {
if (queens[i][j] == 'Q') return false;
}
for (int i = row - , j = col + ; i >= && j < queens.size(); --i, ++j) {
if (queens[i][j] == 'Q') return false;
}
return true;
}
};
我们还可以只使用一个一维数组 queenCol 来保存所有皇后的列位置,初始化均为-1, 那么 queenCol[i] 就是表示第i个皇后在 (i, queenCol[i]) 位置,递归函数还是跟上面的解法相同,就是在当前行数等于n的时候,我们要将 queenCol 还原成一个 nxn 大小的矩阵,并存入结果 res 中。这种记录每个皇后的坐标的方法在验证冲突的时候比较简单,只要从第0行遍历到当前行,若跟之前的皇后的列数相同,直接返回false,叼就叼在判断对角线冲突非常简便,因为当两个点在同一条对角线上,那么二者的横坐标差的绝对值等于纵坐标差的绝对值,利用这条性质,可以快速的判断冲突,代码如下:
解法二:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
vector<int> queenCol(n, -);
helper(, queenCol, res);
return res;
}
void helper(int curRow, vector<int>& queenCol, vector<vector<string>>& res) {
int n = queenCol.size();
if (curRow == n) {
vector<string> out(n, string(n, '.'));
for (int i = ; i < n; ++i) {
out[i][queenCol[i]] = 'Q';
}
res.push_back(out);
return;
}
for (int i = ; i < n; ++i) {
if (isValid(queenCol, curRow, i)) {
queenCol[curRow] = i;
helper(curRow + , queenCol, res);
queenCol[curRow] = -;
}
}
}
bool isValid(vector<int>& queenCol, int row, int col) {
for (int i = ; i < row; ++i) {
if (col == queenCol[i] || abs(row - i) == abs(col - queenCol[i])) return false;
}
return true;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/51
类似题目:
Grid Illumination
参考资料:
https://leetcode.com/problems/n-queens/
http://www.cnblogs.com/TenosDoIt/p/3801621.html
https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 51. N-Queens N皇后问题的更多相关文章
- [LeetCode] 52. N-Queens II N皇后问题 II
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
- [leetcode]51. N-QueensN皇后
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
- LeetCode 51. N-QueensN皇后 (C++)(八皇后问题)
题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...
- Java实现 LeetCode 51 N皇后
51. N皇后 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后问题的解决 ...
- leetcode 51. N皇后 及 52.N皇后 II
51. N皇后 问题描述 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后 ...
- LeetCode(51):N皇后
Hard! 题目描述: n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后问 ...
- leetcode 51 N皇后问题
代码,由全排列转化而来,加上剪枝,整洁的代码: 共有4个变量,res(最终的结果),level,当前合理的解,n皇后的个数,visit,当前列是否放过皇后,由于本来就是在新的行方皇后,又通过visit ...
- [CareerCup] 9.9 Eight Queens 八皇后问题
9.9 Write an algorithm to print all ways of arranging eight queens on an 8x8 chess board so that non ...
- LeetCode: 51. N-Queens(Medium)
1. 原题链接 https://leetcode.com/problems/n-queens/description/ 2. 题目要求 游戏规则:当两个皇后位于同一条线上时(同一列.同一行.同一45度 ...
随机推荐
- LeetCode 733: 图像渲染 flood-fill
题目: 有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. An image is represented by a 2-D array of int ...
- HTML+css基础 css的几种形式 css选择器的两大特性
3.外联样式 css选择器的两大特性 1.继承性:所有跟文本字体有关的属性都会被子元素继承.且权重是0000. 2.层叠性:就是解决选择器权重大小的一种能力,就是看那个选择器的权重大.谁的权重大听谁的 ...
- Kafka随笔
1.选举Leader Leader 是 Partition 级别的,当一个 Broker 挂掉后,所有 Leader 在该 Broker 上的 Partition 都会被重新选举,选出一个新 Lea ...
- C# 中一个限制 Task 并发执行的数量的示例
直接贴代码了: using System; using System.Linq; using System.Threading; using System.Threading.Tasks; class ...
- SQLAlchemy--基本增删改查
目录 简介 安装 组成部分 简单使用 执行原生sql(不常用) orm使用(重点) 常用数据类型 Column常用参数 常用操作(CURD) 创建映射类的实例 创建会话Session 增加add()/ ...
- 关于创建node服务
1.环境条件准备: A.确定node已经创建 B.npm或cnpm已经下载,npm和cnpm其实是一个道理 C.mysql或者使用其他数据库已经安装(本例使用mysql) 2.开始创建,首先新建一个文 ...
- 【分布式搜索引擎】Elasticsearch之开启Elasticsearch的用户名密码验证
一.首先在elasticsearch配置文件中开启x-pack验证, 修改config目录下面的elasticsearch.yml文件,在里面添加如下内容,并重启 xpack.security.ena ...
- SMTP 与 IMAP
(SMTP)邮件传输协议 :电子邮件写好后,由网络传输时的建立在tcp协议基础之上的协议 (IMAP)邮件访问协议:邮件到达目的服务器后,用户从用户的pc ,移动端,等到 接收邮件服务器上去访问自己的 ...
- pytest怎么标记用例?
pytest还有一个很强大的功能,那就是标记用例这个功能,这个功能可真的是很实用哒 首先,我们要实现标记功能,得分为3步走: 1.注册标记 2.标记用例 3.运行已经标记的用例. 那么第一步我们怎么实 ...
- typeof运算对于null会返回“Object"
您也许会问,为什么 typeof 运算符对于 null 值会返回 "Object".这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了.现 ...