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. MQ基本概念

    MQ的基本概念 1) 队列管理器 队列管理器是MQ系统中最上层的一个概念,由它为我们提供基于队列的消息服务. 2) 消息 在MQ中,我们把应用程序交由MQ传输的数据定义为消息,我们可以定义消息的内容并 ...

  2. Java 反射 调用私有构造方法

    单例类: package singleton; public class SingletonTest { // 私有构造方法 private SingletonTest(){ System.out.p ...

  3. flask内容之数据库的管理

    #! /usr/bin/env python # *-* coding: utf-8 *-* from flask import Flask, flash, redirect from flask i ...

  4. 小甲鱼Python第九讲课后习题--010列表

    0.列表都可以存放一些什么东西? 可以存放任何的数据类型 1. 向列表增加元素有哪些方法? append()--末尾添加一个元素 extend()--末尾添加多个元素,但要求已列表的格式添加[x,x, ...

  5. Compile groovy mixed with java in Maven

    Assuming that groovy codes are in src/main/groovy and java codes are in src/main/java. We can use 2 ...

  6. ubuntu redis 自启动配置文件(关机有密码)

    #!/bin/bash # chkconfig : ### BEGIN INIT INFO # Provides: redis-server # Required-Start: $syslog $re ...

  7. idea 集成sonarLint检查代码bugs

    1.目标 idea集成sonar的代码检查,实现可以在提交代码前就检查你的代码,而不是将代码提交之后,之后再去检查. Sonar可以从以下七个维度检测代码质量,而作为开发人员至少需要处理前5种代码质量 ...

  8. WPF 实现窗体拖动

    C# 实现代码 this.Loaded += (r, s) => { this.MouseDown += (x, y) => { if (y.LeftButton == MouseButt ...

  9. iOS scrollsToTop属性失效

    点击状态栏返回顶部失效,是因为scrollView的scrollsToTop属性失效 (继承于scrollView的tableView collectionView也算). 这个属性默认是开启的,然而 ...

  10. 解决Linux文件系统变成只读的方法

    解决Linux文件系统变成只读的方法   解决方法 1.重启看是否可以修复(很多机器可以) 2.使用用 fsck – y /dev/hdc6 (/dev/hdc6指你需要修复的分区) 来修复文件系统 ...