33. N皇后问题(DFS)

本文介绍如何使用深度优先搜索(DFS)算法解决N皇后问题,即在N×N的棋盘上放置N个皇后,使得任意两个皇后不在同一行、列及对角线上。文章详细解释了解决方案的思路与实现代码。

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

描述

n皇后问题是将n个皇后放置在n*n的棋盘上,皇后不能处在同一行、同一列、或同一斜线上,才能保证皇后彼此之间不能相互攻击。

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

每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。


您在真实的面试中是否遇到过这个题?  是

样例

对于4皇后问题存在两种解决的方案:

[

    [".Q..", // Solution 1

     "...Q",

     "Q...",

     "..Q."],

    ["..Q.", // Solution 2

     "Q...",

     "...Q",

     ".Q.."]

]


分析:
本质:深度优先搜索(DFS),隐式图空间,时间复杂度N^N(状态空间)

搜索过程:


我们在试探的过程中,皇后的放置需要检查他的位置是否和已经放置好的皇后发生冲突,为此需要以及检查函数来检查当前要放置皇后的位置,是不是和其他已经放置的皇后发生冲突

假设有两个皇后被放置在(i,j)和(k,l)的位置上,明显,当且仅当|i-k|=|j-l| 时,两个皇后才在同一条对角线上。

当i=k时在同一行上,j=l时在同一列上

(1)先从首位开始检查,如果不能放置,接着检查该行第二个位置,依次检查下去,直到在该行找到一个可以放置一个皇后的地方,然后保存当前状态,转到下一行重复上述方法的检索。 
(2)如果检查了该行所有的位置均不能放置一个皇后,说明上一行皇后放置的位置无法让所有的皇后找到自己合适的位置,因此就要回溯到上一行,重新检查该皇后位置后面的位置。

代码:
class Solution {
public:
    /*
     * @param n: The number of queens
     * @return: All distinct solutions
     */
    vector<vector<string>> solveNQueens(int n) {
        // write your code here
         vector<vector<string> > res;
        vector<int> pos(n, -1);
        solveNQueensDFS(n,pos, 0, res);
        return res;
    }
    void solveNQueensDFS(int n,vector<int> &pos, int row, vector<vector<string> > &res) {
        if (row == n) {
            vector<string> out(n, string(n, '.'));
            for (int i = 0; i < n; ++i) {
                out[i][pos[i]] = 'Q';
            }
            res.push_back(out);
        } else {
            for (int col = 0; col < n; ++col) {
                if (isValid(pos, row ,col)) {
                    pos[row] = col;
                    solveNQueensDFS(n,pos, row + 1, res);
                    pos[row] = -1;
                }
            }
        }
    }
    bool isValid(vector<int> &pos, int row, int col) {
        for (int i = 0; i < row; ++i) {
            if (col == pos[i] || abs(row - i) == abs(col - pos[i])) {
                return false;
            }
        }
        return true;
    }
};



n皇后问题是经典的回溯算法问题之一,目标是在 n×n 的国际象棋棋盘上放置 n 个皇后,使得它们互相之间不能攻击对方。由于皇后的行走规则是可以在横、竖以及斜线上无限移动并吃掉其路径上的棋子,因此我们需要找到一种方案让所有的皇后都不能处于同一条横线、纵线或对角线上。 深度优先搜索(DFS)是一种用于遍历图的数据结构的算法,在解决 n 后面的问题时可以看作是对所有可能性的一种穷举尝试过程,并通过递归来完成这一任务。下面简述一下利用 DFS 来解决问题的基本思想: 1. **初始化**:从第0行开始摆放第一个皇后; 2. **选择合法位置**:对于每一列判断当前位置是否可行(即不会受到之前已放下的皇后的威胁),如果该位置安全,则将此皇后放入对应的位置; 3. **继续放下一个皇后**:当成功地把当前行的一个皇后安置好之后,我们就可以考虑下一行的情况了; 4. **递归调用自身**:重复上述步骤直到最后一行的所有皇后都被妥善安排; 5. **回退操作(Backtracking)**: 如果某一步无法再向前推进(例如到达最后一行也无法满足条件),那么就应回到上一层的状态,改变前一次的选择然后再次尝试其他的可能性; 6. **记录结果集** :每当顺利完成整个棋盘上的布局后保存这份解决方案作为最终的结果; 下面是基于 Python 编写的简单示例代码片段实现了这个思路: ```python def solve_n_queens(n): def dfs(queens, xy_diff, xy_sum): # queens存储已经摆好的皇后所在的列编号,xy_diff存放主对角线信息,xy_sum存副对角线的信息 p = len(queens) if p == n: result.append(queens[:])# 找到了一组解 return None for q in range(n): if q not in queens and p-q not in xy_diff and p+q not in xy_sum:# 检查当前坐标(p,q)能否放置新的皇后 dfs(queens + [q], xy_diff + [p - q], xy_sum + [p + q]) result = [] dfs([], [], []) return [['.'*i+'Q'+'.'*(n-i-1)for i in sol]for sol in result] print(solve_n_queens(4)) ``` 这段程序会返回所有有效的棋局配置列表,其中每个元素代表了一个完整的解向量。这里需要注意的是在实际应用过程中可以根据需要调整输出格式以便于理解和观察。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值