题目描述
题目链接:N皇后问题_牛客题霸_牛客网 (nowcoder.com)
N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。数据范围: 1≤n≤9
要求:空间复杂度 O(1) ,时间复杂度 O(n!)
例如当输入4时,对应的返回值为2,
对应的两种四皇后摆位如下图所示:
示例1
输入:
1返回值:
1
示例2
输入:
8返回值:
92
题目解读
N皇后问题,递归里面的经典题目了。从开始学数据结构,我就经常听到这个题目,但是当时水平太菜,根本看不懂这个题的解析,更别说自己做,时隔如此之久,再次遇到,这次我是看了别人的解析,自己做出来的。 但是,不得不说,这个题的难度还是大,加之其他人的解析也有些问题,看着还是挺费劲。
这个题,就是给一个 n * n 的棋盘, 上面要摆 n 个皇后,也就是一行放一个皇后,但是由于皇后的地位要求,因此要求,任意两个皇后之间,不能在同一行,同一列,也不能在同一条斜线上。如果棋盘的行类 n 较大,人眼去找,也是有点难的,让程序去找,是有点难思考。 而它所要求的,还是找出里面所有的可能性。
解题思想
题意读懂了,那看看如何做,首先从第一行开始放(以 4*4 的格子为例),先放第一列,第一行第一列肯定和谁都不冲突,然后递归进入第二行,第二行先检查第一列,不行;第二列,不行;第三列,可以; 然后进入第三行第一列,不行;第二列,不行,第三列,不行;第四列,不行;回到上一层递归,画图说明这个过程。
应该能容易看到,第二行第三列放一个皇后,再加上第一行第一列的皇后,它俩就把第三行放第三个皇后的所有路都堵死了。堪称一夫当关万夫莫开了。 那回退到第二行之后,看第四列,然后再继续往下放,如下图,
能看得出来,这下是 第四个皇后的生机被完全抹杀了。皇后那是多尊贵的身份,四个主子谁也惹不得,既然第二个皇后怎么放都不行,那就把第一个皇后的位置也给调了。如下图,
好了,很完美,四位傲娇的皇后,都有她们满意的宫廷了。这就是找到一个可能性的过程,剩下的与上相似,相信你,看完已经懂了。 那就看看代码吧!
代码注释
import java.util.*;
public class Solution {
/**
*
* @param n int整型 the n
* @return int整型
*/
// write code here
// 用来记录排列皇后的可能性
int possible=0;
public int Nqueen (int n) {
/* 用来记录已经放置皇后的位置,用这个数组下标记录皇后所在行,下标对应的值,
记录皇后所在的列
*/
int[] pos = new int[n];
// 进行递归
recursion(n,0,pos);
return possible;
}
public void recursion(int n,int row,int[] pos){
// 如果当前所在行,已经为n了,表明已经超过放皇后的格子了,也就是n个皇后,
// 排完了,那就进行计数加 1
if(row == n){
possible++;
return;
}
for(int i=0;i<n;i++){
// 在当前行当前列 放皇后之前,先去检查之前放到皇后的位置
if(isValid(pos,row,i)){
// 如果满足条件,就把当前行当前列计入数组
pos[row]=i;
recursion(n,row+1,pos);
}
}
}
public boolean isValid(int[] pos,int row,int col){
// 查看当前行之前的皇后所在位置,与当前行当前列 有没有同行同列或者同一斜线的
for(int i=0;i<row;i++ ){
if( col== pos[i] || Math.abs(row-i)== Math.abs(col-pos[i]))
return false;
}
return true;
}
}