连接图
有向图问题
无向图问题
无向图最短路径
分析:对于无向图最短路径问题,建议使用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函数 里涉及的查询操作也是一样的过程。)
卡子哥:代码随想录 (programmercarl.com)
矩阵图
分析:定义移动矩阵
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)
分析:消除边界岛屿再如上所示。