[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;
        }
};
原文地址:https://www.cnblogs.com/hellojamest/p/12273470.html