684. Redundant Connection
仅供自己学习
思路:
这种要找出让树出现环而不成为树的边,可以通过查并集来寻找,因为当我们按顺序遍历所有节点。如果是树,那么就会遍历所有边到的都是目前的新结点,也就是没有加入树,不是同一个查并集里面的,也就不成环了,遍历后才会加入树才进入相同的查并集,但如果遍历边,边的两个端点是同一个查并集的,那是不是就是这条边让整条树成环了,那么就直接返回这条边就可以了。
代码:
1 class Solution { 2 public: 3 int find(int node1,vector<int>& parent){ 4 if(parent[node1]!=node1) { 5 parent[node1]=find(parent[node1],parent); 6 } 7 return parent[node1]; 8 } 9 void _union(vector<int>& parent,int node1,int node2){ 10 parent[find(node1,parent)]=find(node2,parent); 11 } 12 vector<int> findRedundantConnection(vector<vector<int>>& edges) { 13 int size=edges.size(); 14 vector<int> parent(size+1); 15 for(int i=1;i<=size;++i){ 16 parent[i]=i; 17 } 18 for(auto& edge:edges){ 19 int node1=edge[0]; 20 int node2=edge[1]; 21 if(find(node1,parent)!=find(node2,parent)){ 22 _union(parent,node1,node2); 23 }else return edge; 24 } 25 return {}; 26 } 27 };
DFS的办法,无向图用邻接链表存储,然后每次遍历边同样判断两个端点是不是连接在一起,判断连接在一起的条件为,edges[0]的邻接链表有edges[1]或者他的邻接链表中有和edges[1]相连的节点。
这里的pre有个作用就是避免两点之间有两条边 即1-2,2-1这样的情况,避免死循环
代码:
1 class Solution { 2 public: 3 bool sameleader(int node1,int node2,unordered_map<int,unordered_set<int>>& mp,int pre){ 4 if(mp[node1].count(node2)) return true; 5 for(auto& nei:mp[node1]){ 6 if(nei==pre) continue; 7 if(sameleader(nei,node2,mp,node1)) return true; 8 } 9 return false; 10 } 11 vector<int> findRedundantConnection(vector<vector<int>>& edges) { 12 unordered_map<int,unordered_set<int>> mp(edges.size()+1); 13 for(auto& edge:edges){ 14 if(sameleader(edge[0],edge[1],mp,-1)) return edge; 15 mp[edge[0]].insert(edge[1]); 16 mp[edge[1]].insert(edge[0]); 17 } 18 return {}; 19 } 20 };
还有一个BFS的方法
这个需要一个数据结构来存放访问过的节点,和一个队列用来BFS。首先遍历边,每遍历一个新边就要重新创建一个数据结构存放访问过的节点,然后将改变的edges[0]加入进队列和数据结构中。只要队列不为空,就循环,判断edges[0]的邻接表中没有edges[1],如果有就返回edge,没有的话就遍历邻接链表中的节点,判断这些节点和edges[1]有没有相连,也就是在这些节点的邻接表中,如果有就返回,没有就添加进队列和访问过的节点中去。当队列q空后,就把edge[0],[1]加入进hash链表中,这样这两个点就连在了一起。
代码:
1 class Solution { 2 public: 3 4 vector<int> findRedundantConnection(vector<vector<int>>& edges) { 5 unordered_map<int,unordered_set<int>> mp(edges.size()+1); 6 queue<int> q; 7 8 for(auto edge:edges){ 9 unordered_set<int> visited; 10 q.push(edge[0]); 11 visited.insert(edge[0]); 12 while(!q.empty()){ 13 int temp=q.front();q.pop(); 14 if(mp[temp].count(edge[1])) return edge; 15 for(auto& nei:mp[temp]){ 16 if(visited.count(nei)) continue; 17 q.push(nei); 18 visited.insert(nei); 19 } 20 } 21 mp[edge[0]].insert(edge[1]); 22 mp[edge[1]].insert(edge[0]); 23 } 24 return {}; 25 } 26 };