算法之图论

连接图

有向图问题

无向图问题

无向图最短路径

127. 单词接龙 - 力扣(LeetCode)

分析:对于无向图最短路径问题,建议使用BFS(对点的扩展关联(扩散迭代方式))。

           同时由于无向性注意建立查找集合Visit(防止进入循环)。

           建立uset 方便查找

           建立umap 方便查重并记录

思路:uset 记录所有wordlist中的word,通过bfs获得满足条件(uset找到,umap未出现)的点,并在umap记录(word + 现路径长度)。

并查集问题

并查集常用来解决连通性问题。

        即:当我们需要判断两个元素是否在同一个集合里的时候,用并查集。

并查集四步走:1)初始化 2)寻根 3)比较 4)合并

class Solution {
private:
    int n = 1005; // 节点数量3 到 1000
    vector<int> father = vector<int> (n, 0); // C++里的一种数组结构

    // 并查集初始化
    void init() {
        for (int i = 0; i < n; ++i) {
            father[i] = i;
        }
    }
    // 并查集里寻根的过程
    int find(int u) {
        return u == father[u] ? u : father[u] = find(father[u]);
    }
    // 判断 u 和 v是否找到同一个根
    bool isSame(int u, int v) {
        u = find(u);
        v = find(v);
        return u == v;
    }
    // 将v->u 这条边加入并查集
    void join(int u, int v) {
        u = find(u); // 寻找u的根
        v = find(v); // 寻找v的根
        if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
        father[v] = u;
}

并查集主要有两个功能:

  • 将两个元素添加到一个集合中。
  • 判断两个元素在不在同一个集合

涉及路径压缩:靠压缩路径来缩短查询根节点的时间。

路径压缩后的并查集时间复杂度在O(logn)与O(1)之间,且随着查询或者合并操作的增加,时间复杂度会越来越趋于O(1)。(解释:在第一次查询的时候,相当于是n叉树上从叶子节点到根节点的查询过程,时间复杂度是logn,但路径压缩后,后面的查询操作都是O(1),而 join 函数 和 isSame函数 里涉及的查询操作也是一样的过程。)

题目:684. 冗余连接 - 力扣(LeetCode)

卡子哥:代码随想录 (programmercarl.com)

矩阵图

200. 岛屿数量 - 力扣(LeetCode)

分析:定义移动矩阵

    int direction[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};

BFS作法 对于最短路径题,岛屿题比较上手

class Solution {
public:

    int dect[4][2] = {1,0,-1,0,0,1,0,-1};
    int numIslands(vector<vector<char>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        queue<pair<int, int>> q;
        int res = 0;
        for (int i(0); i < n; i++) {
            for (int j(0); j < m; j++) {
                if(grid[i][j] == '0') continue;
                q.push(pair<int, int>(i, j));
                grid[i][j] = '0';
                while (!q.empty()) {
                    int sz = q.size();
                    while (sz--) {
                        auto temp = q.front();q.pop();
                        for (int k(0); k < 4; k++) {
                            int x = temp.first + dect[k][0];
                            int y = temp.second + dect[k][1];
                            if (x < 0||y < 0||x >= n||y >= m) continue;
                            if (grid[x][y] == '0') continue;
                            if (grid[x][y] == '1') {
                                grid[x][y] = '0';
                                q.push(pair<int, int>(x, y));
                            }
                        }
                    }
                }
                res++;
            }
        }
        return res;
    }
};

DFS作法 岛屿题需要used矩阵作为回溯支撑。

1254. 统计封闭岛屿的数目 - 力扣(LeetCode) 

分析:消除边界岛屿再如上所示。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值