Leetcode之回溯法专题-51. N皇后(N-Queens)
Leetcode之回溯法专题-51. N皇后(N-Queens)
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."], ["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。 分析:输入一个N,求在这个N*N的面板里,N皇后的解法。要求是,放置了一个皇后时,该皇后的 行 列 不能存在其他皇后,且2个对角线上也不能有皇后。
利用回溯法可以解答这一题,首先初始化一个N*N的数组,并在其值上设置成'.'。
char mp[][] = new char[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mp[i][j] = '.';
}
}
然后我们new一个存答案的List,
List<List<String>> ans = new ArrayList<>();
在写DFS之前,我们需要写一个boolean型的ok函数,用于判断一个棋盘是否符合要求:
public boolean ok(char[][] mp, int len, int x, int y) {
// check row
for (int i = 0; i < len; i++) {
if (i == y)
continue;
if (mp[x][i] == 'Q')
return false;
} // check col
for (int i = 0; i < len; i++) {
if (i == x)
continue;
if (mp[i][y] == 'Q')
return false;
} // x=1 y=3
int cnt = 0;
int up = 0;
int down = 0; for(int i=y+1;i<len;i++){
up = (++cnt)*-1+x;
down = cnt*1+x; if(up<len && up>=0){
//System.out.println("mp[up][i]=["+up+"]["+i+"]");
if(mp[up][i]=='Q')
return false;
} if(down>=0 && down<len){
//System.out.println("mp[down][i]=["+down+"]["+i+"]");
if(mp[down][i]=='Q'){
return false;
}
}
} //System.out.println("other");
cnt = 0;
for(int i=y-1;i>=0;i--){
up = (++cnt)*-1+x;
down = cnt*1+x; if(up<len && up>=0){
//System.out.println("mp[up][i]=["+up+"]["+i+"]");
if(mp[up][i]=='Q')
return false;
} if(down>=0 && down<len){
//System.out.println("mp[down][i]=["+down+"]["+i+"]");
if(mp[down][i]=='Q'){
return false;
}
}
} return true;
}
下一步开始写dfs函数,
第一个参数是mp数组,是这一副棋盘,
第二个参数是n,代表的是棋盘的大小,
第三个参数是i,把2维的矩阵转换为1维了,例如i=1就对应着(0,1)这个点,以此类推。
第四个参数是queen,用来存现在放的棋子的个数。
public void dfs(char[][] mp, int len, int i,int queen) {
int x = i / len;
int y = i % len; if ((x >= len || y >= len)) {
if(queen!=len) return;
List<String> list = new ArrayList<>();
for (int a = 0; a < len; a++) {
String tmp = "";
for (int b = 0; b < len; b++) {
tmp += mp[a][b];
}
list.add(tmp);
}
ans.add(list);
return;
}
dfs(mp,len,i+1,queen);
if (ok(mp, len, x, y)) {
mp[x][y] = 'Q';
dfs(mp, len, i + 1,queen+1);
mp[x][y] = '.';
} }
整合一下,最后的AC代码为:
class Solution {
List<List<String>> ans = new ArrayList<>(); public List<List<String>> solveNQueens(int n) { char mp[][] = new char[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mp[i][j] = '.';
}
}
dfs(mp, n, 0,0); return ans;
} public void dfs(char[][] mp, int len, int i,int queen) {
int x = i / len;
int y = i % len; if ((x >= len || y >= len)) {
if(queen!=len) return;
List<String> list = new ArrayList<>();
for (int a = 0; a < len; a++) {
String tmp = "";
for (int b = 0; b < len; b++) {
tmp += mp[a][b];
}
list.add(tmp);
}
ans.add(list);
return;
}
dfs(mp,len,i+1,queen);
if (ok(mp, len, x, y)) {
mp[x][y] = 'Q';
dfs(mp, len, i + 1,queen+1);
mp[x][y] = '.';
} } public boolean ok(char[][] mp, int len, int x, int y) {
// check row
for (int i = 0; i < len; i++) {
if (i == y)
continue;
if (mp[x][i] == 'Q')
return false;
} // check col
for (int i = 0; i < len; i++) {
if (i == x)
continue;
if (mp[i][y] == 'Q')
return false;
} // x=1 y=3
int cnt = 0;
int up = 0;
int down = 0; for(int i=y+1;i<len;i++){
up = (++cnt)*-1+x;
down = cnt*1+x; if(up<len && up>=0){
//System.out.println("mp[up][i]=["+up+"]["+i+"]");
if(mp[up][i]=='Q')
return false;
} if(down>=0 && down<len){
//System.out.println("mp[down][i]=["+down+"]["+i+"]");
if(mp[down][i]=='Q'){
return false;
}
}
} //System.out.println("other");
cnt = 0;
for(int i=y-1;i>=0;i--){
up = (++cnt)*-1+x;
down = cnt*1+x; if(up<len && up>=0){
//System.out.println("mp[up][i]=["+up+"]["+i+"]");
if(mp[up][i]=='Q')
return false;
} if(down>=0 && down<len){
//System.out.println("mp[down][i]=["+down+"]["+i+"]");
if(mp[down][i]=='Q'){
return false;
}
}
} return true;
} }
Leetcode之回溯法专题-51. N皇后(N-Queens)的更多相关文章
- Leetcode之回溯法专题-52. N皇后 II(N-Queens II)
Leetcode之回溯法专题-52. N皇后 II(N-Queens II) 与51题的代码80%一样,只不过52要求解的数量,51求具体解,点击进入51 class Solution { int a ...
- Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)
Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III) 同类题目: Leetcode之回溯法专题-39. 组合总数(Combination Sum) Lee ...
- Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)
Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...
- Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning)
Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning) 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. ...
- Leetcode之回溯法专题-90. 子集 II(Subsets II)
Leetcode之回溯法专题-90. 子集 II(Subsets II) 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入 ...
- Leetcode之回溯法专题-79. 单词搜索(Word Search)
Leetcode之回溯法专题-79. 单词搜索(Word Search) 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元 ...
- Leetcode之回溯法专题-78. 子集(Subsets)
Leetcode之回溯法专题-78. 子集(Subsets) 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = ...
- Leetcode之回溯法专题-77. 组合(Combinations)
Leetcode之回溯法专题-77. 组合(Combinations) 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输 ...
- Leetcode之回溯法专题-47. 全排列 II(Permutations II)
Leetcode之回溯法专题-47. 全排列 II(Permutations II) 给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例: 输入: [1,1,2] 输出: [ [1,1,2] ...
随机推荐
- LINUX下查找大文件及大的文件夹
原帖地址:https://www.cnblogs.com/iyoume2008/p/6105590.html 今天正好碰到这样的问题,在博客园中看到有以上地址的一篇文章,照着上面的操作解决了问题,但是 ...
- PHP使用array_unique对二维数组去重处理
去重,点这里,东西是好东西,就是有点懒.莫见怪
- linux初学者-网络桥接篇
linux初学者-网络桥接篇 在网络的使用中,有时需要搭建网络桥来实现网络桥接.例如在一台主机上制作一台虚拟机,虚拟机是没有物理网卡的,这时虚拟机数据的发送和接收就需要通过主机上的物理网卡,需要主机的 ...
- 【Arduino】37种传感器系列实验(4)---振动传感器模块
---恢复内容开始--- 37款传感器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器,依照实践(动手试试)出真知的理念,以学习和交流为 ...
- JavaScript Boolean(逻辑)对象
Boolean(逻辑)对象用于将非逻辑值转换为逻辑值(true 或者 false). 实例 检查逻辑值 检查逻辑对象是 true 还是 false. 完整的 Boolean 对象参考手册 我们提供 J ...
- React入门理解demo
1.React文档结构 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- javaweb入门-----request与response的作用
request对象和request对象的原理 1.request和response对象request对象和request对象的原理时由服务器创建的,我们来使用它们 2.request对象是来获取请求消 ...
- python 实现两个文本文件内容去重
实现两个文本内容去重,输出两个文本不重复的结果 两个测试文本内容如下 1.txt中内容为 1 2 3 4 5 6 7 8 2.txt中内容为 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- html以前没有学到的标签
<q>标签,短文本引用 <blockquote>标签,长文本引用 <address>标签,为网页加入地址信息 <code>标签,插入单行代码 <p ...
- 激活函数、正向传播、反向传播及softmax分类器,一篇就够了!
1. 深度学习有哪些应用 图像:图像识别.物体识别.图片美化.图片修复.目标检测. 自然语言处理:机器创作.个性化推荐.文本分类.翻译.自动纠错.情感分析. 数值预测.量化交易 2. 什么是神经网络 ...