LeetCode51. N皇后(回溯算法)

文章介绍了如何使用回溯算法解决N皇后问题,即在n×n的棋盘上放置n个皇后,要求皇后之间不能在同一行、同一列或同一对角线上。解题策略是通过递归地尝试在每一行放置皇后并检查冲突,如果找到可行解则保存,否则回溯撤销放置。代码示例展示了具体的实现过程,包括初始化棋盘、回溯函数、有效性判断等关键步骤。
摘要由CSDN通过智能技术生成

1. 题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

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

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

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


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/n-queens


2. 解题思路

 N皇后问题:
    皇后们的约束条件是:
    1. 不能使同行
    2. 不能是同列
    3. 不能同对角线
    棋盘可以看作是一个矩阵,我们在放置皇后时,为了找到一种解法,
    我们从上到下,从左到右判断每个位置是否可以放置皇后。
   



    void backtracking(参数:总行数n, 当前行数row, 棋盘二维数组) {
    if (终止条件:row == n时,说明已经遍历完每一行的元素了,可以将棋盘的结果添加到返回的容器中了) {
        存放结果;
        return;
    }
    for (选择:每一行的位置) {
        if(符合放置条件):
            处理该节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
        }
    }


3. 代码

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        //1. 首先对二维数组进行初始化,将每一个位置初始化为‘.’
        char[][] chessboard = new char[n][n];
        for(char[] c: chessboard){
            Arrays.fill(c,'.');
        }
        //2. 进行回溯遍历
        backTracking(n, 0, chessboard);
        return res;
    }

    public void backTracking(int n, int row, char[][] chessboard){
        //1. 终止条件,遍历完整个棋盘就可以保存结果了
        if(row == n){
            //2. 数组转化成List容器
            res.add(Arrays2List(chessboard));
            return;
        }
        //3. 单层搜索的逻辑
        for(int col = 0;col < n;col++){
            // 4. 判断是否可以在这个位置放置皇后
            if(isValid(row, col, n, chessboard)){
                chessboard[row][col] = 'Q';
                backTracking(n, row+1, chessboard);
                chessboard[row][col] = '.';
            }
        }
    }

    // 2. 将二维数组棋盘转为 泛型为String的List容器
    public List<String> Arrays2List(char[][] chessboard){
        List<String> list = new ArrayList<String>();
        for(char[] c: chessboard){
            list.add(String.copyValueOf(c));
        }
        return list;
    }
    // 4. 判断有效性
    /**
    为何没有判断同一行上是否有皇后呢?
        这是因为,在单层搜索逻辑中,已经处理了这种情况,单层搜索每一行时,只可能有一个皇后。
     */
    public boolean isValid(int row, int col, int n, char[][] chessboard){
        //a. 判断在该位置上的同一列上是否有皇后
        for(int i = 0; i < row; i++){
            if(chessboard[i][col] == 'Q'){
                return false;
            }
        }
        //b. 判断左对角线上是否有皇后 
        for(int i = row-1,j = col-1; i >= 0 && j >=0; i--,j--){
            if(chessboard[i][j] == 'Q'){
                return false;
            }
        }
        //c. 判断右对角线上是否有皇后
        for(int i = row-1, j = col+1; i >= 0 && j < n;i--,j++){
            if(chessboard[i][j] == 'Q'){
                return false;
            }
        }
        // 可以放置皇后
        return true;   
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值