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. Yii2 数据搜索类 PostSearch

    数据搜索类 PostSearch /** * @Purpose : 添加 authorName 属性,使属性和搜索表单相对应 * @return array */ public function at ...

  2. PAT基础6-1

    6-1 简单输出整数 (10 分) 本题要求实现一个函数,对给定的正整数N,打印从1到N的全部正整数. 函数接口定义: void PrintN ( int N ); 其中N是用户传入的参数.该函数必须 ...

  3. C#自动识别文件编码

    以下代码源自:http://www.cnblogs.com/stulzq/p/6116627.html /// <summary> /// 用于取得一个文本文件的编码方式(Encoding ...

  4. Vue(二十二)vuex小案例(官网计数案例整合)

    1.使用 vue-cli 创建项目(具体操作可以参考前面的文章) ... 2.下载 vuex - npm install vuex -S 3.将 vuex 添加到项目中 (1)在项目中创建store文 ...

  5. .NET项目引用黄色小三角以及找不到依赖的解决方法

    上图,问题描述: 经过查证,这个是引用的项目框架版本和本项目框架版本不一致的症状. 解决办法: 点击项目右键属性,调整版本使两个项目的版本一致 问题解决.good! ----------------- ...

  6. 【最大公约数&链表】权值 @upcexam5921

    时间限制: 1 Sec 内存限制: 512 MB 题目描述 给定一个长为n的正整数序列Ai.对于它的任意一个连续的子序列{Al, Al+1, …, Ar},定义其权值W (l, r)为其长度与序列中所 ...

  7. Unity 5.4版本 Application.systemLanguage 失效

    最近在上线双语版本(一个包支持中文.英文二种语言)时,遇到一个坑点 if (ToolUtils.isAndroid()) { if (Application.systemLanguage == Sys ...

  8. RestTemplate发送请求并携带header信息 RestTemplate post json格式带header信息

    原文地址:  http://www.cnblogs.com/hujunzheng/p/6018505.html RestTemplate发送请求并携带header信息   v1.使用restTempl ...

  9. bootstrap-3-验证表单

    js: $('#nqs-add-userxinxi-form').bootstrapValidator({ message: 'This value is not valid', excluded : ...

  10. python 2 字典的基本使用

    dicVisit={} if not dicVisit.has_key(visitKey):#不存在 diaSet = set() diaSet.add(diagnoseContent) dicVis ...