图的表示
图的比较方便的表示方法有两种,第一种是matrix(比如有number of island这种),第二种是邻接矩阵的形式。
如果题目中给了边的信息,最好转化成邻接矩阵。
DFS
void dfs(graph, visited, current){
if (visited[current]) return;
visited[current] = true; // Need to set this line first
for (auto neighbor:graph[current]){
if(!visited[neighbor]) {
dfs(graph,visited, neighbor);
}
}
}BFS
并查集
在判断联通情况的时候可以和dfs/bfs互换,union find优点是可以方便处理动态图,缺点是并不是O(1)time,而bfs/dfs相反。
在面试的时候可以写两个并查集版本,一个是简易版本,一个是完整带weighted quick-union and path compression的版本。
class UF { // 完整版本
// union-find, bfs
int N;
int[] id;
int[] sz;
int segments;
public UF(int n){
N = n;
segments = n;
id = new int[N];
sz = new int[N];
for(int i=0; i<N; i++){
id[i] = i;
sz[i] = 1;
}
}
public int root(int i) {
while(i!=id[i]){
id[i] = id[id[i]]; // path compression
i = id[i];
}
return i;
}
public void connect(int p, int q){
int i = root(p);
int j = root(q);
if(i == j) return;
if(sz[i]<sz[j]) { // if-else: weighted quick-union
id[i] = j;
sz[j] += sz[i];
}
else if(sz[i]>sz[j]) {
id[j] = i;
sz[i] += sz[j];
}
else {
id[j] = i;
sz[i] += sz[j];
}
segments--;
}
public boolean connected(int p, int q) {
if(root(p)==root(q)){
return true;
}
return false;
}
}简单版本 (LC261代码)
public class Solution {
public boolean validTree(int n, int[][] edges) {
// initialize n isolated islands
int[] nums = new int[n];
Arrays.fill(nums, -1);
// perform union find
for (int i = 0; i < edges.length; i++) {
int x = find(nums, edges[i][0]);
int y = find(nums, edges[i][1]);
// if two vertices happen to be in the same set
// then there's a cycle
if (x == y) return false;
// union
nums[x] = y;
}
return edges.length == n - 1;
}
int find(int nums[], int i) {
if (nums[i] == -1) return i;
return find(nums, nums[i]);
}
}
本文介绍了图的两种表示方法:邻接矩阵和边集合,并详细解释了深度优先搜索(DFS)和广度优先搜索(BFS)的实现方式。此外还探讨了并查集在图中的应用,包括一个简单的并查集实现和一个带有加权快速联合及路径压缩优化的完整版本。
10万+

被折叠的 条评论
为什么被折叠?



