[Leetcode]684.Redundant Connection
链接:LeetCode684
在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。
相关标签:并查集
这道题给我们了一个无向图,让删掉组成环的最后一条边。思路是,每加入一条边,就进行环检测,一旦发现了环,就返回当前边。对于无向图,还是用邻接表来保存,建立每个结点和其所有邻接点的映射,由于两个结点之间不算有环,所以要避免这种情况 1->{2}, 2->{1} 的死循环,,参见代码如下:
python:
class Solution:
def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
dic = {}
n = len(edges)
def find(p):
while p!=dic[p]:
p = dic[p]
return p
def union(p,q):
root1,root2 = find(p),find(q)
if root1==root2:
return True
else:
dic[root1] = root2
return False
for i in range(1,n+1):
dic[i] = i
for edge in edges:
if union(edge[0],edge[1]):
return edge
C++:
class Solution {
public:
vector<int> findRedundantConnection(vector<vector<int>>& edges) {
unordered_map<int,int> dic;
int n = edges.size();
for(int i=1;i<n+1;++i){
dic[i] = i;
}
for(auto edge:edges){
int p=edge[0],q=edge[1];
if(hasCycle(p,q,dic)) return edge;
}
return vector<int>{};
}
int find(int p,unordered_map<int,int> &dic){
while(p!=dic[p]){
p = dic[p];
}
return p;
};
bool hasCycle(int p,int q,unordered_map<int,int>& dic){
int root1 = find(p,dic),root2 = find(q,dic);
if(root1 == root2) return true;
dic[root1] = root2;
return false;
}
};