BM59 N皇后问题
题目描述
N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。
数据范围: 1<=n<=9,1≤n≤9
要求:空间复杂度 O(1) ,时间复杂度 O(n!)
一、思路引出
n皇后问题属于典型的深度优先思想算法设计题,一般是依次遍历所有行,在每行内遍历寻找所有不冲突的可摆放列,找到该行一个不冲突的列,递归到下一行继续寻找不冲突的列,直到递归至最后一行找到一种可能的摆放方式
二、算法设计
1.Java代码
①递归模块
//深度优先搜寻可能的摆放方式
public void search(int row, int n){
//遍历当前行(第row行)的全部列,找到该行所有不冲突的可选择的摆放位置
for(int col=1; col<=n; col++){
//按顺序先摆放一个皇后,之后调用place方法判断放置在该位置是否会造成冲突
queen[row] = col;
if(place(row) && row<=n){
if(row==n){
put_ways++;//不冲突且该行已为最后一行,则说明找到了一种新的摆放方式
}else{
search(row+1, n);//不冲突则递归去下一行寻找不冲突的摆放位置
}
}//遍历当前行所有列并完成之后行的递归后,程序将回溯至上一行
}
}
②冲突判断
//判断刚刚放置在第row行的皇后是否会和之前行的皇后发生冲突
public boolean place(int row){
for(int last_row=1; last_row<row; last_row++){
//分别判断是否存在纵向冲突和斜向冲突
if(queen[last_row]==queen[row] || Math.abs(queen[last_row]-queen[row])==row-last_row){
return false;
}
}
return true;
}
③完整代码
import java.util.*;
public class Solution {
/**
*
* @param n int整型 the n
* @return int整型
*/
private int put_ways;//累加计算摆放方式
private int[] queen;//queen数组依次存储1-n行各行的摆放列号
public Solution(){
this.put_ways = 0;
}
public int Nqueen (int n) {
if(n<=0){
return 0;
}
queen = new int[n+1];
search(1, n);
return put_ways;
}
//深度优先搜寻可能的摆放方式
public void search(int row, int n){
//遍历当前行(第row行)的全部列,找到该行所有不冲突的可选择的摆放位置
for(int col=1; col<=n; col++){
//按顺序先摆放一个皇后,之后调用place方法判断放置在该位置是否会造成冲突
queen[row] = col;
if(place(row) && row<=n){
if(row==n){
put_ways++;//不冲突且该行已为最后一行,则说明找到了一种新的摆放方式
}else{
search(row+1, n);//不冲突则递归去下一行寻找不冲突的摆放位置
}
}
}
}
//判断刚刚放置在第row行的皇后是否会和之前行的皇后发生冲突
public boolean place(int row){
for(int last_row=1; last_row<row; last_row++){
//分别判断是否存在纵向冲突和斜向冲突
if(queen[last_row]==queen[row] || Math.abs(queen[last_row]-queen[row])==row-last_row){
return false;
}
}
return true;
}
}
2、效率分析
该算法属于回溯法,时间复杂度为O(n!),这里的代码不调用ArrayList等类库,直接采用数组进行计算,获得了较高效率
总结
上一次做这题已经是两年半之前了,大一大二的时候数据结构算法项目不知道做了几十个,全都用的C,指针玩得还算熟练,结果现在做这题居然还花了点时间