• 【Leetcode】 51. N 皇后


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

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

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

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

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

    示例 2

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

    提示

    1 <= n <= 9
    
    • 1

    已经不是第一次遇到 N 皇后问题了,依稀记得三年前的暑假,刚接触 c++的自己,看着 N 皇后别人 AC 掉的代码,天书一般,留下了满眼的钦佩!

    • 愿与君共勉!

    事实上,现在看来,N 皇后问题相比其他的回溯算法题,hard点在于它使用的是二维数组,回溯的思路是不变的!

    void backtracking(参数) {
        if (终止条件) {
            存放结果;
            return;
        }
        for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
            处理节点;
            backtracking(路径,选择列表); // 递归
            回溯,撤销处理结果
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 参数选择 -> 回溯终止条件 -> 单层处理logic

    值得一提的是 每列棋子放置的合理性判别,即 isValid的函数实现。


    AC

    /*
     * @lc app=leetcode.cn id=51 lang=cpp
     *
     * [51] N 皇后
     */
    
    // @lc code=start
    class Solution {
    private:
        vector<vector<string>> result;
        bool isValid(int row, int col, vector<string>& chessboard, int n) {
            // 检查列
            for(int i = 0; i < row; i++) {
                if(chessboard[i][col] == 'Q')
                    return false;
            }
            // 检查45°角
            for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
                if(chessboard[i][j] == 'Q')
                    return false;
            }
            // 检查135°角
            for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
                if(chessboard[i][j] == 'Q')
                    return false;
            }
            return true;
        }
        void backtracking(int n, int row, vector<string>& chessboard) {
            if(n == row) {
                result.push_back(chessboard);
                return ;
            }
            for(int col = 0; col < n; col++) {
                if(isValid(row, col, chessboard, n)) {
                    chessboard[row][col] = 'Q';
                    backtracking(n, row + 1, chessboard);
                    chessboard[row][col] = '.';
                }
            }
        }
    public:
        vector<vector<string>> solveNQueens(int n) {
            result.clear();
            std::vector<std::string> chessboard(n, std::string(n, '.'));
            backtracking(n, 0, chessboard);
            return result;
        }
    };
    // @lc code=end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    AC


    【补充】cpp 哈希表
    C++中哈希表可以分为以下几类:

    1. unordered_map :基于哈希表实现的 Key-Value 映射容器,支持快速的插入、查找和删除操作。

    下面是 unordered_map 常见的使用方式:

    #include 
    #include 
    using namespace std;
    
    int main() {
        // 创建一个空的unordered_map
        unordered_map<string, int> umap;
    
        // 插入元素
        umap["apple"] = 10;
        umap.insert(make_pair("orange", 20));
    
        // 访问元素
        int apple_price = umap["apple"];
        int orange_price = umap.at("orange");
    
        // 遍历元素
        for (auto it = umap.begin(); it != umap.end(); it++) {
            cout << it->first << " : " << it->second << endl;
        }
    
        // 删除元素
        umap.erase("apple");
        umap.clear();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. unordered_set :基于哈希表实现的无序集合容器,支持快速的插入、查找和删除操作。和 unordered_map 相似,只是不需要存储键值对。

    下面是 unordered_set 常见的使用方式:

    #include 
    #include 
    using namespace std;
    
    int main() {
        // 创建一个空的unordered_set
        unordered_set<string> uset;
    
        // 插入元素
        uset.insert("apple");
        uset.insert("orange");
    
        // 查找元素
        if (uset.find("apple") != uset.end()) {
            cout << "Found apple!" << endl;
        }
    
        // 遍历元素
        for (auto it = uset.begin(); it != uset.end(); it++) {
            cout << *it << endl;
        }
    
        // 删除元素
        uset.erase("apple");
        uset.clear();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. unordered_multimap :基于哈希表实现的 Key-Value 映射容器,支持插入重复的 Key,每个 Key 对应多个 Value。和 unordered_map 相似,只是可以插入重复 Key 和多个 Value。

    下面是 unordered_multimap 常见的使用方式:

    #include 
    #include 
    using namespace std;
    
    int main() {
        // 创建一个空的unordered_multimap
        unordered_multimap<string, int> umap;
    
        // 插入元素
        umap.insert(make_pair("apple", 10));
        umap.insert(make_pair("orange", 20));
        umap.insert(make_pair("apple", 30));
    
        // 访问元素
        auto range = umap.equal_range("apple");
        for (auto it = range.first; it != range.second; it++) {
            cout << it->first << " : " << it->second << endl;
        }
    
        // 遍历元素
        for (auto it = umap.begin(); it != umap.end(); it++) {
            cout << it->first << " : " << it->second << endl;
        }
    
        // 删除元素
        umap.erase("apple");
        umap.clear();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1. unordered_multiset :基于哈希表实现的无序集合容器,支持插入重复的元素。和 unordered_set 相似,只是可以插入重复元素。

    下面是 unordered_multiset 常见的使用方式:

    #include 
    #include 
    using namespace std;
    
    int main() {
        // 创建一个空的unordered_multiset
        unordered_multiset<string> uset;
    
        // 插入元素
        uset.insert("apple");
        uset.insert("orange");
        uset.insert("apple");
    
        // 查找元素
        if (uset.count("apple") > 0) {
            cout << "Found apple!" << endl;
        }
    
        // 遍历元素
        for (auto it = uset.begin(); it != uset.end(); it++) {
            cout << *it << endl;
        }
    
        // 删除元素
        uset.erase("apple");
        uset.clear();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    以上是哈希表的四种常见用法,需要根据具体业务场景选择相应的容器。

  • 相关阅读:
    CISP-PTE真题演示
    iOS 17 测试版中 SwiftUI 视图首次显示时状态的改变导致动画“副作用”的解决方法
    一文让你彻底了解多线程
    极速Go语言入门(超全超详细)-基础篇2
    Android学习笔记 23. ViewPager
    js对象获取属性的方法(.和[]方式)
    《学习强国》投稿发稿全攻略:三种方式助你实现投稿梦想!
    ubuntu软件源
    Cocos Creator3.8 项目实战(九)2D UI DrawCall优化详解(下)
    数组传回后端总显示为空怎么解决
  • 原文地址:https://blog.csdn.net/qq_54053990/article/details/133691110