N-Queens -- 回溯法 -- 力扣101算法题解笔记

6.3N-Queens -- 回溯法

题目描述

先说一下,这个题目十分之困难。

给定一个大小为n的正方形国际象棋棋盘,求有多少种方式可以放置n个皇后,并使得她们互不攻击,即每一行、列、左斜、右斜最多只有一个皇后

输入输出样例

Input :4

Output: \[".Q..", "...Q","Q...","..Q.", // Solution 1

"..Q.", "Q...","...Q",".Q.."] // Solution 2

注:.表示空白位置,Q代表皇后

题解

类似于在矩阵中寻找字符串,本体也是通过修改状态矩阵来进行回溯操作,不同的是,我们需要对每一行列,左斜右斜,建立访问数组,来记录他们是否存在皇后。

注意,本题有一个隐藏条件,是满足条件的结果中每一行或列有且仅有一个皇后。这是因为我们一共只有n行n列。所以,如果我们通过对每一行遍历来插入皇后,我们就不需要对行建立访问数组了。

这个是缓解这题难度的关键

cpp 复制代码
#include <vector>
#include <iostream>
using namespace std;

void backtracking(vector<vector<string>>& ans, vector<string>& board, 
    vector<bool> &column, vector<bool> &ldiag, vector<bool> &rdiag, int row, int n) {
    if (row == n) {
        ans.push_back(board);
        return;
    }
    for (int i = 0; i < n; ++i) {
        if (column[i] || ldiag[n - row + i - 1] || rdiag[row + i + 1]) {
            continue;
        }
        //修改当前节点状态
        board[row][i] = 'Q';
        column[i] = ldiag[n - row + i - 1] = rdiag[row + i + 1] = true;
        //递归子节点
        backtracking(ans, board, column, ldiag, rdiag, row + 1, n);
        //回改当前节点状态
        board[row][i] = '.';
        column[i] = ldiag[n - row + i - 1] = rdiag[row + i + 1] = false;
    }
}

vector<vector<string>> solveNQueens(int n) {
    vector<vector<string>> ans;
    if (n == 0) {
        return ans;
    }
    vector<string> board(n, string(n, '.'));
    vector<bool> column(n, false), ldiag(2 * n - 1, false), rdiag(2 * n - 1, false);
    backtracking(ans, board, column, ldiag, rdiag, 0, n);
    return ans;
}

int main() {
    int n = 4;
    vector<vector<string>> res = solveNQueens(n);
    for (int i = 0; i < res.size(); ++i) {
        cout << "[";
        for (int j = 0; j < res[i].size(); ++j) {
            cout << "   \"" << res[i][j] << "\"";
            if (j != res[i].size() - 1) {
                cout << ",";
            }
            cout << endl;
        }
        if (i != res.size() - 1) {
            cout << "  ]," << endl;
        }
        else {
            cout << "  ]" << endl;
        }
        cout << "  // Solution " << i + 1 << endl;
    }
    cout << "]" << endl;
    return 0;
}
相关推荐
吞下星星的少年·-·6 分钟前
线段树模板
算法
橙淮16 分钟前
并发编程(六)
java·jvm
段一凡-华北理工大学19 分钟前
2026 高炉炼铁智能化技术全景与演进路径~系列文章11:演进路径与行业未来
大数据·网络·人工智能·算法·工业智能体·高炉炼铁智能化
拽着尾巴的鱼儿22 分钟前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影28 分钟前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
叶小鸡1 小时前
小鸡玩算法-力扣HOT100-多维动态规划
算法·leetcode·动态规划
星马梦缘1 小时前
aaaaa
数据结构·c++·算法
EntyIU1 小时前
JVM内存与GC笔记
java·jvm·笔记
OpenApi.cc1 小时前
神经网络结构驱动+数据结构分析
数据结构·人工智能·神经网络
XS0301062 小时前
并发编程 六
java·后端