DFS学习初步二(N Queens问题)(Java实现)

本文探讨了N皇后问题的解决方法,介绍了如何通过深度优先搜索(DFS)算法寻找n个皇后在n×n棋盘上的非攻击性布局。文章详细解释了判断皇后位置合法性的条件,并提供了Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看一下N皇后问题

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

这里写图片描述

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

示例:

输入: 4
输出: [
[“.Q..”, // 解法 1
“…Q”,
“Q…”,
“..Q.”],

[“..Q.”, // 解法 2
“Q…”,
“…Q”,
“.Q..”]
]
解释: 4 皇后问题存在两个不同的解法。

思路

这种类型的问题其实主要是在于对于所有情况的一次遍历比如说我们可以看图
这里写图片描述
可以看到查找可以用的有效解的过程是深度优先搜索DFS的过程,其实就是递归进行搜索的过程,需要注意的是进行递归之后,为了重复利用空间,我们需要取消先前搜索过程中的建立的标记我们将所有遍历后的结果,打印出来就是这个题目的解法了
这个题目使用C语言去解题需要使用较为频繁的指针操作所以我们使用Java来解题

重点

需要注意的是
我们需要使用程序语言来描述皇后问题的具体要求,如果说我们现在有两个皇后的坐标分别是(x,y)(i,j),比如说同一横行的两个皇后,我们使用x==i来描述,同一个主对角线的两个皇后我们使用x-y==i-j来表示,而同一副对角线的两个皇后的位置关系我们使用x+y==i+j来表示,这是筛选的必要条件也是对于八皇后问题的数学抽象

class solution {
    public List<List<String>> solveNQueens(int n) {
        char [][] board =new char[n][n];//初始化棋盘
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                board[i][j]='.';
                }
        }
        List<List<String>> res =new ArrayList<List<String>>();//创建存储结果的二二维List
        dfs(board,0,res);//启动DFS
        return res;
    }
    //先进行第一列的遍历,然后换第二列的不同行然后...
    private void dfs(char [][] board,int colIndex,List<List<String>> res){
        if(colIndex==board.length){//已经递归至最后一列
            res.add(structList(board));
            return ;
        }

        for(int i=0;i<board.length;i++){
            if(validate(board,i,colIndex)){
                board[i][colIndex]='Q';
                dfs(board,colIndex+1,res);//递归遍历
                board[i][colIndex]='.';//取消标记
            }
        }
    }
    //验证摆放棋盘的位置合法性
    private boolean validate(char [][] board,int x,int y){
        for(int i=0;i<board.length;i++){
            for(int j=0;j<y;j++){
                if(board[i][j]=='Q'&&(x+j==i+y||x+y==i+j||x==i))
                    return false;
            }
        }
        return true ;
    }
    //将遍历结果进行格式化
    private List<String> structList(char[][] board){
        List<String> res =new LinkedList<String>();
         for(int i=0;i<board.length;i++){
             String s=new String (board[i]);
             res.add(s);           
         }   
         return res;        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值