问题说明
联合查询主要用于检查图里面是否有回环。
leetcode684、leetcode990这两个题就是用联合查询来做的。
联合集的概念及联合查询
联合集假设初始时,所有的元素都在不同的set内,连接两个元素后,这两个元素就属于同一个set。leetcode684的题就是可以用联合集来做:
刚开始假设所有的节点都在不同的set内,连接两个节点之后就设置这两个节点在同一个set。当新加入的某一条边的两个节点都在同一个set,就说明这两个节点已经可以通过一定的路径连接了,所以新加入的边就是冗余边。
演示
假设现在有6个节点1-6,我们向这些节点加入边。初始化时节点及对应的集合如下:
| 节点 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 所属集合 | 1 | 2 | 3 | 4 | 5 | 6 |
加入边3-6后的节点及对应集合:
| 节点 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 所属集合 | 1 | 2 | 3 | 4 | 5 | 3 |
加入边1-3后的节点及对应集合:
| 节点 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 所属集合 | 1 | 2 | 1 | 4 | 5 | 3 |
加入边1-6。加入边之前可以发现1、6这两个节点已经属于同一个set,因此1-6这条边是冗余边。
联合方法
联合查询的关键方法有两个:
一个是找到元素是哪个集合的findSet()
一个是联合两个集合为一个union()
leetcode684
684的思路如下:刚开始默认每个节点属于不同的集合,每加入一条边就联合两个节点或者两个集合;当查到两个节点已经属于同一个集合的时候,这条边就是冗余边。
class Solution {
public int[] findRedundantConnection(int[][] edges) {
int[] us=new int[2000];
for(int i=0;i<2000;i++)
us[i]=i;
for(int[] e:edges) {
if(findSet(e[0], us)==findSet(e[1], us))
return e;
union(e[0],e[1], us);
}
return null;
}
private int findSet(int num, int[] us) {
if(num==us[num]) return num;
while(us[num]!=num)
num=us[num];
return num;
}
private void union(int start, int end, int[] us) {
int startSet = findSet(start, us);
int endSet = findSet(end, us);
if(startSet!=endSet) {
us[endSet]=startSet;
}
}
}
leetcode990
leetcode的思路为,首先默认所有的字母对应不同的数值。先扫一遍所有的等式,联合所有呆联合的节点;然后再扫一遍所有的不等式,如果存在一个不等式,两边的字母属于同一个集合就返回false。
class Solution {
public boolean equationsPossible(String[] equations) {
int[] union=new int[26];
for(int i=0;i<26;i++)
union[i]=i;
int p1=0,p2=0,p1Set=0, p2Set=0;
for(String e:equations) {
p1=e.charAt(0)-'a';
p2=e.charAt(3)-'a';
p1Set = findSet(p1, union);
p2Set = findSet(p2, union);
if(e.charAt(1)=='='&&p1Set!=p2Set) {
union[p2Set] = p1Set;
}
}
for(String e:equations) {
if(e.charAt(1)=='!') {
p1=e.charAt(0)-'a';
p2=e.charAt(3)-'a';
p1Set = findSet(p1, union);
p2Set = findSet(p2, union);
if(p1Set==p2Set)
return false;
}
}
return true;
}
private int findSet(int p, int[] union) {
if(union[p]!=p) {
return findSet(union[p], union);
}
return p;
}
}

本文深入探讨了联合查询的基本概念及其在解决图中回环问题的应用,通过LeetCode上的两个题目,leetcode684和leetcode990,详细阐述了如何使用联合查询来识别冗余边和处理等式关系。文章提供了具体的代码实现,帮助读者理解联合查询中的关键方法findSet()和union(),并展示了如何在实际问题中运用这一算法。
2389

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



