Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

思路1:打表
public class Solution {
public int totalNQueens(int n) {
int[] result = new int[] { 0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724,
2680, 14200, 73712, 365596, 2279184, 14772512, 95815104,
666090624 };
return result[n];
}
}

思路2:使用回溯法,參照http://blog.csdn.net/mlweixiao/article/details/40984541

public class Solution {
public static int num=0;
private boolean isValid(List<Integer> al) {
int column = al.get(al.size() - 1);
for (int i = 0; i < al.size() - 1; i++) {
if (column == al.get(i)
|| Math.abs(column - al.get(i)) == Math.abs(al.size()-1 - i)) {
return false;
}
}
return true;
} private void search(int n, List<Integer> al, int col) {
if (col > n){
num++;
}else {
for (int j = 0; j < n; j++) {
al.add(j);
if (isValid(al)) {
search(n, al, col + 1);
}
al.remove(al.size()-1);
}
}
}
public int totalNQueens(int n) {
num=0;
search(n,new LinkedList<Integer>(),1);
return num;
}
}

思路3 :回溯法。仅仅只是使用位移,速度超快,參考http://blog.csdn.net/kai_wei_zhang/article/details/8033194

如果棋盘的前i-1行已经被填充。如今我们须要填充第i行,那怎么得出第i行哪些是能够填充呢?那么有三种情况是禁止,同一列,斜率k为1的斜线,斜率k为-1的斜线。要是我们能用三个变量row。ld。rd来分别存储这三种情况的禁止位该多好啊。

以下是是六皇后问题的,如果前三行已经填充了。我们须要填充第四行


当中row。ld,rd的二进制表示如上,1代表禁止位,0代表空位(能够放皇后)。

对于第四行而言。那么第1,3。5列(从左往右数)不能放,故row的二进制表示为101010;对于第四行而言。斜率k为1的斜线有两条对其有影响,最左上的一条对第四行没有影响,k=1的中间一条斜线对第四行的影响是第一个位置(从左往右数)不能放,k=1的右下一条斜线对第四行的影响是第4个位置(从左往右数)不能放。故k=1的斜线对第四行的影响为100100(从左往右数);而k=-1的三条斜线对第四行的影响各自是第4,5,6个位置(从左往右数)不能放,故rd的二进制表示为000111(从左往右数),那么这三个数row。rd。ld二进制取‘或’就能够得到101111。101111对于第四行而言就意味着仅仅有第二个位置能放。

那么第四行填充了,这三个数row,rd。ld该怎么变化呢?row与刚填充的第二个位置(用010000表示)取或就可以。rd与刚填充的第二个位置(用010000表示)取或。还要向右移1位,由于其斜率为-1,第四行的禁止位相对于第五行而言是左上。同理,ld与刚填充的第二个位置(用010000表示)取或。还要向左移1位。当row的二进制的全部位全为1时,则表示填充完毕。


public class Solution {
// sum用来记录皇后放置成功的不同布局数。upperlim用来标记全部列都已经放置好了皇后。 static int counter = 0;
static long upperlim = 1;
// 试探算法从最右边的列開始,函数带三个參数row、ld和rd。分别表示在纵列和两个对角线方向的限制条件下这一行的哪些地方不能放
void search(long row, long ld, long rd) {
if (row != upperlim) {
// row,ld。rd进行“或”运算,求得全部能够放置皇后的列,相应位为0。
// 然后再取反后“与”上全1的数。来求得当前全部能够放置皇后的位置。相应列改为1
// 也就是求取当前哪些列能够放置皇后
long pos = upperlim & ~(row | ld | rd);
while (pos != 0) { // 0 -- 皇后没有地方可放,回溯
// 拷贝pos最右边为1的bit。其余bit置0
// 也就是取得能够放皇后的最右边的列
long p = pos & -pos;//相当于p = pos & (~pos + 1) // 将pos最右边为1的bit清零
// 也就是为获取下一次的最右可用列使用做准备,
// 程序将来会回溯到这个位置继续试探
pos -= p; // row + p,将当前列置1,表示记录这次皇后放置的列。
// (ld + p) << 1。标记当前皇后左边相邻的列不同意下一个皇后放置。 // (ld + p) >> 1,标记当前皇后右边相邻的列不同意下一个皇后放置。
// 此处的移位操作实际上是记录对角线上的限制。仅仅是由于问题都化归
// 到一行网格上来解决。所以表示为列的限制就能够了。显然。随着移位
// 在每次选择列之前进行,原来N×N网格中某个已放置的皇后针对其对角线
// 上产生的限制都被记录下来了
search(row + p, (ld + p) << 1, (rd + p) >> 1);
}
} else {
// row的全部位都为1,即找到了一个成功的布局,回溯
counter++;
}
}
public int totalNQueens(int n) {
counter = 0;
upperlim = (1 << n) - 1;
test(0, 0, 0);
return counter;
}
}

LeetCode 51 N-Queens II的更多相关文章

  1. LeetCode Single Number I / II / III

    [1]LeetCode 136 Single Number 题意:奇数个数,其中除了一个数只出现一次外,其他数都是成对出现,比如1,2,2,3,3...,求出该单个数. 解法:容易想到异或的性质,两个 ...

  2. [array] leetcode - 40. Combination Sum II - Medium

    leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...

  3. LeetCode 137. Single Number II(只出现一次的数字 II)

    LeetCode 137. Single Number II(只出现一次的数字 II)

  4. LeetCode:路径总和II【113】

    LeetCode:路径总和II[113] 题目描述 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径. 说明: 叶子节点是指没有子节点的节点. 示例:给定如下二叉树, ...

  5. LeetCode:组合总数II【40】

    LeetCode:组合总数II[40] 题目描述 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candi ...

  6. leetcode 51. N-Queens 、52. N-Queens II

    51. N-Queens 使用isValid判断当前的位置是否合法 每次遍历一行,使用queenCol记录之前行的存储位置,一方面是用于判断合法,另一方面可以根据存储结果输出最终的结果 class S ...

  7. leetcode 51. N皇后 及 52.N皇后 II

    51. N皇后 问题描述 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后 ...

  8. [Leetcode] n queens ii n皇后问题

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  9. [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 ...

随机推荐

  1. 生成Area URL链接

    关于Area的URL链接生成,可以分为这么三种情况:第一种是在当前Area生成指向当前Area的链接:第二种是生成指向其他Area的链接:第三种是在某个Area中生成指向根目录的链接.下面是这三种情况 ...

  2. 小甲鱼Python视频课后答案(第一讲)---仅记录学习

    1.python是什么语言? Python是一种支持面向对象的解释性高级语言,属于脚本语言的一种. 2.IDLE是什么? IDLE是开发python程序的基本IDE(集成开发环境),具备基本的IDE的 ...

  3. python之模块3

    RE模块使用方法 (1)finditer  返回迭代器 (2)search:只匹配第一个结果 import re res=re.search("\d+","djksf34 ...

  4. Accumulator<Long> implements of JavaSparkContext in Spark1.x

    As we all know , up to Spark 1.6.2, JavaSparkContext only provides two kinds of accumulators: Intege ...

  5. 【二维树状数组】计数问题 @JSOI2009/upcexam5911

    时间限制: 1 Sec 内存限制: 128 MB 题目描述 一个n*m的方格,初始时每个格子有一个整数权值.接下来每次有2种操作: 改变一个格子的权值: 求一个子矩阵中某种特定权值出现的个数. 输入 ...

  6. centos7 快速安装 mariadb(mysql)

    从最新版本的linux系统开始,默认的是 Mariadb而不是mysql! 使用系统自带的repos安装很简单: yum install mariadb mariadb-server systemct ...

  7. ConditionalOnProperty

    配置Spring Boot通过@ConditionalOnProperty来控制Configuration是否生效 1.matchIfMissing属性:从application.properties ...

  8. 版本控制:tortoise svn的 revert to this revision和 revert changes from this revision有什么区别?

    问题: The link: http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-howto-rollback.html describes ...

  9. [Linux] - 网速测试命令

    Windows网速测试方法有很多,或者可以直接使用浏览器去一些网站上搜索测试即可. 在Linux中其实更容易,只需要一行命令即可搞定: curl -s https://raw.githubuserco ...

  10. Webhook 实践 —— 自动部署

    https://segmentfault.com/a/1190000007892407 安装nodejs 安装nodejs建议直接下载二进制包,把官网上的64位二进制版本下载地址复制下来,执行 wge ...