原题链接:
https://leetcode.cn/problems/find-if-path-exists-in-graph/
完成情况:
解题思路:
这段代码实现了一个并查集数据结构,并用它来判断从源节点到目标节点是否存在一条有效路径。
具体实现包括以下几个方法:
1. validPath方法:初始化并查集,遍历边数组,将边加入并查集,最后判断源节点和目标节点是否在同一个集合中。
2. init方法:初始化并查集,将每个节点的父节点指向自己。
3. find方法:在并查集中寻找根节点的过程,采用路径压缩的方式优化查找速度。
4. isSame方法:判断两个节点是否在同一个集合中,即它们的根节点是否相同。
5. join方法:将两个节点所在的集合合并为一个集合。
整体来说,这段代码使用并查集来维护节点之间的关系,通过路径压缩和按秩合并等优化方式提高了查找和合并的效率,从而判断源节点到目标节点是否存在有效路径。
参考代码:
package 代码随想录.并查集;
public class _1971寻找图中是否存在路径 {
int [] fatherPaths;
/**
*
* @param n n个节点
* @param edges 指示出来所有的连接边
* @param source 开头
* @param destination 结尾
* @return 返回是否能从 【开头 -> 结尾 】
*/
public boolean validPath(int n, int[][] edges, int source, int destination) {
fatherPaths = new int[n]; //存储n
initUnion();
for (int i = 0; i < edges.length; i++) {
joinPath(edges[i][0],edges[i][1]);
}
return isConnect(source,destination);
}
/**
* 初始化并查集
*/
private void initUnion() {
for (int i = 0; i < fatherPaths.length; i++) {
fatherPaths[i] = i;
}
}
/**
* 判断两个节点是否能够相互连通
* @param nodeA
* @param nodeB
* @return
*/
private boolean isConnect(int nodeA, int nodeB) {
//两个节点均不断去寻找其最上层的节点
nodeA = findNode(nodeA);
nodeB = findNode(nodeB);
return nodeA == nodeB;
}
/**
* 将两个节点连通起来
* @param sourceNode
* @param destNode
*/
private void joinPath(int sourceNode, int destNode) {
//分别寻找它们的上级根节点
sourceNode = findNode(sourceNode);
destNode = findNode(destNode);
if (sourceNode == destNode) return; //如果这两个根相等,说明已经是同一个节点了
fatherPaths[destNode] = sourceNode; //我默认为source方向指出来,其作为上级节点
}
/**
* 寻找其父节点
* @param itsRootNode
* @return
*/
private int findNode(int itsRootNode) {
if (itsRootNode == fatherPaths[itsRootNode]){
return itsRootNode; //已经到了头,其自己作为自己的根节点
}else {
fatherPaths[itsRootNode] = findNode(fatherPaths[itsRootNode]); //递归去找自己的上级(父)节点
return fatherPaths[itsRootNode];
}
}
}