The n-queens puzzle is the problem of placing nqueens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return the number of distinct solutions to the n-queens puzzle.

Example:

Input: 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown below.
[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],  ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

这道题是之前那道 N-Queens 的延伸,说是延伸其实我觉得两者顺序应该颠倒一样,上一道题比这道题还要稍稍复杂一些,两者本质上没有啥区别,都是要用回溯法 Backtracking 来解,如果理解了之前那道题的思路,此题只要做很小的改动即可,不再需要求出具体的皇后的摆法,只需要每次生成一种解法时,计数器加一即可,代码如下:

解法一:

class Solution {
public:
int totalNQueens(int n) {
int res = ;
vector<int> pos(n, -);
helper(pos, , res);
return res;
}
void helper(vector<int>& pos, int row, int& res) {
int n = pos.size();
if (row == n) ++res;
for (int col = ; col < n; ++col) {
if (isValid(pos, row, col)) {
pos[row] = col;
helper(pos, row + , res);
pos[row] = -;
}
}
}
bool isValid(vector<int>& pos, int row, int col) {
for (int i = ; i < row; ++i) {
if (col == pos[i] || abs(row - i) == abs(col - pos[i])) {
return false;
}
}
return true;
}
};

但是其实我们并不需要知道每一行皇后的具体位置,而只需要知道会不会产生冲突即可。对于每行要新加的位置,需要看跟之前的列,对角线,及逆对角线之间是否有冲突,所以我们需要三个布尔型数组,分别来记录之前的列 cols,对角线 diag,及逆对角线 anti_diag 上的位置,其中 cols 初始化大小为n,diag 和 anti_diag 均为 2n。列比较简单,是哪列就直接去 cols 中查找,而对角线的话,需要处理一下,如果我们仔细观察数组位置坐标的话,可以发现所有同一条主对角线的数,其纵坐标减去横坐标再加n,一定是相等的。同理,同一条逆对角线上的数字,其横纵坐标之和一定是相等的,根据这个,就可以快速判断主逆对角线上是否有冲突。任意一个有冲突的话,直接跳过当前位置,否则对于新位置,三个数组中对应位置都赋值为 true,然后对下一行调用递归,递归返回后记得还要还原状态,参见代码如下:

解法二:

class Solution {
public:
int totalNQueens(int n) {
int res = ;
vector<bool> cols(n), diag( * n), anti_diag( * n);
helper(n, , cols, diag, anti_diag, res);
return res;
}
void helper(int n, int row, vector<bool>& cols, vector<bool>& diag, vector<bool>& anti_diag, int& res) {
if (row == n) ++res;
for (int col = ; col < n; ++col) {
int idx1 = col - row + n, idx2 = col + row;
if (cols[col] || diag[idx1] || anti_diag[idx2]) continue;
cols[col] = diag[idx1] = anti_diag[idx2] = true;
helper(n, row + , cols, diag, anti_diag, res);
cols[col] = diag[idx1] = anti_diag[idx2] = false;
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/52

类似题目:

N-Queens

参考资料:

https://leetcode.com/problems/n-queens-ii/

https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution

https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)

LeetCode All in One 题目讲解汇总(持续更新中...)

最新文章

  1. 《徐徐道来话Java》(1):泛型的基本概念
  2. 背水一战 Windows 10 (17) - 动画: ThemeTransition(过渡效果)
  3. html5视频播放插件
  4. MySQL支持的数据类型(2)( 日期)
  5. 【leetcode】 Remove Duplicates from Sorted List
  6. 20145213《Java程序设计》实验报告一:Java开发环境的熟悉(Windows+IDEA)
  7. iScroll.js和Swiper.js联合使用时的插件冲突(滑动冲突)
  8. easyui datagrid 表格组件列属性formatter和styler使用方法
  9. Flex:在PANEL的title上加一个button[转]
  10. WF系列——工作流基本知识
  11. 存储数据键和项目对的类(Dictionary对象)
  12. HDU 3374 String Problem
  13. 201621123050 《Java程序设计》第7周学习总结
  14. 豌豆夹Redis解决方案Codis源码剖析:Dashboard
  15. PowerDesigner 批量添加字段
  16. Python—os模块介绍
  17. Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)
  18. Linux运维之Ansible自动化运维管理工具
  19. 第十二周作业_PSP总结报告
  20. CMDB之数据采集

热门文章

  1. CSS3属性 box-shadow 向框添加一个或多个阴影
  2. Centos 上 Tengine安装
  3. 记录软件工程课程项目开发时遇到的各种小问题(django)
  4. 微服务(Microservices)—Martin Fowler【翻译】
  5. Be a new gentlemen
  6. 一个Java文件至多包含一个公共类
  7. jQuery中的$.extend方法来扩展JSON对象及合并,方便调用对象方法
  8. 用css隐藏元素的5种方法
  9. ipython notebook 浏览器中编写数学公式和现实
  10. 取代SharedPreferences的多进程解决方案