力扣hot100--DFS/BFS

DFS/BFS算法经典问题解析

目录

DFS/BFS

1. 79. 单词搜索

2. 200. 岛屿数量

3. 437. 路径总和 III

4. n-皇后问题


DFS/BFS

1. 79. 单词搜索

中等

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board 和 word 仅由大小写英文字母组成

// 定义一个Solution类,用于解决二维网格中查找单词的问题
class Solution {
public:
    // 定义四个方向的移动向量,分别对应上、右、下、左
    int dx[4]{1,0,-1,0};
    int dy[4]{0,-1,0,1};
    
    // 使用深度优先搜索(DFS)和回溯算法来查找单词
    bool dfs(vector<vector<char>>& board, string word, int k, int i, int j, vector<vector<int>> &visit) {
        // 如果当前字符不匹配,直接返回false
        if(word[k] != board[i][j]) {
            return false;
        } else if (k == word.size() - 1) {
            // 如果已经匹配到最后一个字符,返回true
            return true;
        }

        visit[i][j] = 1; // 标记当前位置为已访问
        bool result = false;
        // 遍历四个方向
        for (int d{}; d < 4; ++d) {
            // 计算新的位置
            int i1 = i + dx[d];
            int j1 = j + dy[d];

            // 检查新位置是否在网格内
            if (min(i1, j1) < 0 || i1 >= board.size() || j1 >= board[0].size()) {
                continue;
            }

            // 如果新位置已被访问过,跳过
            if (1 == visit[i1][j1]) continue;

            // 递归搜索新位置
            if (dfs(board, word, k + 1, i1, j1, visit)) {
                result = true;
                break;
            } 
        }
        
        visit[i][j] = 0; // 回溯,将当前位置标记为未访问
        return result;
    }

    // 主函数,用于判断网格中是否存在给定的单词
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size(), n = board[0].size();
        vector<vector<int>> visit(m, vector<int>(n)); // 初始化访问标记矩阵
        // 遍历网格的每个位置,以每个位置为起点进行DFS
        for (int i{}; i < m; ++i) {
            for (int j{}; j < n; ++j) {
                bool flag{false};
                flag = dfs(board, word, 0, i, j, visit);
                i

这段代码定义了一个优先队列(priority queue),用于图算法中,比如 **Prim 算法** 或 **Dijkstra 算法**。它的作用是维护一组边,并按照权重从小到大排序。 --- ### ✅ 语法解析 ```cpp priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> out_edges; ``` #### 各部分含义: 1. `pair<int, int>`: - 表示每个元素是一个键值对。 - 通常用于表示一条边:第一个值可能是目标节点,第二个值是边的权重(如 `(to_node, cost)`)。 2. `vector<pair<int, int>>`: - 表示底层使用的容器是 `vector`。 - 优先队列内部使用一个容器来存储数据,默认是 `vector`。 3. `greater<>()`: - 是一个比较函数对象,用于定义“小顶堆”。 - 默认情况下,`priority_queue` 是大顶堆(即最大的元素排在最前面)。 - 使用 `greater<>()` 可以让优先队列变成**小顶堆**,即最小的元素排在最前面。 4. `out_edges`: - 这个变量名表示该优先队列用于存储“当前节点可以扩展出去的边”,并按权重从小到大排序。 --- ### 🧠 示例说明 假设我们有一个图,当前节点为 `0`,它连接了以下边: - 到节点 `1`,权重为 `5` - 到节点 `2`,权重为 `3` - 到节点 `3`,权重为 `7` 那么这些边会被插入到 `out_edges` 中: ```cpp out_edges.push({1, 5}); out_edges.push({2, 3}); out_edges.push({3, 7}); ``` 由于使用的是 `greater<>()`,出队顺序将是: 1. `{2, 3}` 2. `{1, 5}` 3. `{3, 7}` 这正是我们需要的“最小权重优先”的特性。 --- ### ✅ 在 Prim 算法中的用途 在最小生成树的 Prim 算法中,这个优先队列用来记录当前已选节点所连接的所有未访问节点及其边权,每次取出权重最小的边进行处理。 --- ### 总结 - `priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> out_edges;` 定义了一个按权重升序排列的优先队列。 - 每个元素是一个 `pair<int, int>`,通常表示边的目标节点和权重。 - 使用 `greater<>()` 实现了“小顶堆”,适合最小生成树等贪心算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值