力扣第51题N皇后

文章介绍了N皇后问题的解决方案,这是一个使用递归和回溯策略在N*N棋盘上放置N个皇后,确保它们不在同一行、列或对角线上的经典算法问题。解法中详细阐述了检查和放置皇后的逻辑,并提供了相应的Java代码实现。
摘要由CSDN通过智能技术生成

一、题目:51. N皇后

二、题目解析

改题属于,递归加回溯的题目,题意是在N*N的棋盘上,如何放置N个皇后,使其不能在同一行,同一列,以及斜对角线上。

解法1:

假设我们要检查(4,3)这个位置,由于皇后是按行摆放的,所以就不用检查一行了。

由于是从上到下摆放,第5行、第6行、第7行还没有皇后,那么Q往下的竖线、斜线都不用检查。

竖线部分只要检查(3,3)、(2,3)、(1,3)、(0,3)这几个位置就可以了。

Q左边那条斜线,不断往左上方遍历,坐标变化是(3,2)、(2,1)、(1,0),每次都是x-1,y-1。

Q右边那条斜线,不断往右上方遍历,坐标变化是(3,4)、(2,5)、(1,6)、(0,7),每次都是x-1,y+1。

所以三个循环,一个检查竖线、一个检查左边斜线、一个检查右边斜线,就完成了整个校验过程。

以4 * 4格子的递归调用树如下:

三、代码如下:

class Solution {
    public List<List<String>> solveNQueens(int n) {
        //生成N*N的棋盘
        char[][] arr = new char[n][n];
        //填充棋盘,每个格子默认是“.”表示没有放置皇后
        for(int i=0;i<n;++i) {
            Arrays.fill(arr[i],'.');
        }
        List<List<String>> res = new ArrayList<List<String>>();
        dfs(arr,0,n,res);
        return res;
    }
    //检查当前的行和列是否可以放置皇后
    private boolean check(char[][] arr,int x,int y,int n) {
        //检查竖着的一列是否有皇后
        for(int i=0;i<x;++i) {
            if(arr[i][y]=='Q') {
                return false;
            }
        }
        //检查左上到右下的斜边是否有皇后
        int i=x-1, j=y-1;
        while(i>=0 && j>=0) {
            if(arr[i][j]=='Q') {
                return false;
            }
            --i;
            --j;
        }
        //检查左下到右上的斜边是否有皇后
        i = x-1;
        j = y+1;
        while(i>=0 && j<n) {
            if(arr[i][j]=='Q') {
                return false;
            }
            --i;
            ++j;
        }
        return true;
    }

    private void dfs(char[][] arr,int x,int n,List<List<String>> res) {
        //x是从0开始计算的,当x==n时所有行的皇后都放置完毕,此时记录结果
        if(x==n) {
            List<String> ans = new ArrayList<String>();
            for(int i=0;i<n;++i) {
                StringBuilder tmp = new StringBuilder();
                for(int j=0;j<n;++j) {
                    if(arr[i][j]=='.') {
                        tmp.append(".");
                    } else {
                        tmp.append("Q");
                    }
                }
                ans.add(tmp.toString());
            }
            res.add(ans);
            return;
        }
        //遍历每一列
        for(int y=0;y<n;++y) {
            //检查[x,y]这一坐标是否可以放置皇后
            //如果满足条件,就放置皇后,并继续检查下一行
            if(check(arr,x,y,n)) {
                arr[x][y] = 'Q';
                dfs(arr,x+1,n,res);
                arr[x][y] = '.';
            }
        }
    }
}

四、测试

五、结束

六、详细解答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Run,boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值