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;
}
相关推荐
码少女15 小时前
数据结构——哈希表的基础
数据结构·散列表
KaMeidebaby15 小时前
卡梅德生物技术快报|抗体亲和力成熟工业化调控新机制:差异性浆细胞增殖工艺优化思路
java·开发语言·人工智能·算法·机器学习·架构·spark
luj_176815 小时前
心形曲线轨迹控制三大关键技术
c语言·开发语言·c++·经验分享·算法
tmlx3I08116 小时前
高光谱拼接算法(六)RANSAC 误匹配剔除
人工智能·算法·机器学习
不相心 -w-16 小时前
基础-滑动窗口-(定长 | 不定长)
算法
醉城夜风~16 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法
ysa05103016 小时前
【板子】ST表
c++·笔记·算法·板子
CHHH_HHH17 小时前
【C++11】深入解析C++可变参数模板
开发语言·c++·算法·stl·c++11
hurrycry_小亦17 小时前
洛谷题目:P1215 [USACO1.4] 母亲的牛奶 Mother‘s Milk 题解(本题简)
算法
数智化转型推荐官17 小时前
2026统一身份管理系统五大发展趋势解读
java·运维·微服务