0
点赞
收藏
分享

微信扫一扫

深度优先算法练习

棒锤_45f2 2022-04-29 阅读 73

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,指针玩得还算熟练,结果现在做这题居然还花了点时间

举报

相关推荐

0 条评论