LeetCode热题100 N 皇后

题目描述

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

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

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

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

示例 1:


输入 :n = 4
输出\[".Q...","...Q","Q...","...Q.","...Q.","Q...","...Q",".Q..."]
解释 :如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入 :n = 1
输出\["Q"]

提示:

1 <= n <= 9

思路

1 进行dfs,每层代表选取的行数,层内只需要遍历列数。

2 每个位置需要判断列、主对角线、副对角线是否重复,行不需要判断,因为dfs将层隔开了。

3 主对角线和副对角线的表示可以用 x + y 和 y - x 表示,注意y - x可能是负数,所以需要进行偏正为y - x + n。

代码

cpp 复制代码
class Solution {
public:
    
    vector<vector<string>> solveNQueens(int n) {
        // 记录多个答案
        vector<vector<string>>ans;
        // 记录单个答案
        vector<string>res;
        // 记录每层的答案
        string s(n, '.');

        // 某一列是否被标记
        vector<bool> st_col(n, false); 
        // 主对角线是否被标记
        vector<bool> main_diag(n * 2, false);
        // 次对角线是否被标记
        vector<bool> sub_diag(n * 2, false);

        // 每层枚举一行的所有列
        dfs(0, n, st_col, main_diag, sub_diag, s, res, ans);

        return ans;
    }

    void dfs(int row, int n, vector<bool> &st_col, vector<bool> &main_diag, vector<bool> &sub_diag, string &s, vector<string>&res, vector<vector<string>> &ans)
    {
        if(res.size() == n)
        {
            ans.push_back(res);
            return;
        }

        // 每层枚举一行的所有列
        for(int col = 0; col < n; ++col)
        {
            // 没有列、主副对角线冲突
            if(st_col[col] == false && main_diag[row + col] == false && sub_diag[col - row + n] == false)
            {
                st_col[col] = true;
                main_diag[row + col] = true;
                sub_diag[col - row + n] = true;
                s[col] = 'Q';
                res.push_back(s);
                s[col] = '.'; // 提前复原, 下一层要用到
                dfs(row + 1, n, st_col, main_diag, sub_diag, s, res, ans);
                st_col[col] = false;
                main_diag[row + col] = false;
                sub_diag[col - row + n] = false;
                res.pop_back();
            }
        }
    }

};
相关推荐
祖力558 小时前
数据结构的基本概念与单向链表(链表数据类型构造、创建、头插、尾插、头删、尾删)
数据结构·链表
大明者省9 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_79811 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander25811 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
ShineWinsu12 小时前
对于C++:C++11中lambda、function、bind的解析
c++·面试·笔试·开发·lambda·bind·function
码匠许师傅12 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
Shell运维手记12 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI12 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型13 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光13 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口