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 };

 

posted @ 2021-03-29 15:29  Mrsdwang  阅读(38)  评论(0编辑  收藏  举报