leetcode684:冗余连接

TOleetcode684:冗余连接

leetcode684:冗余连接

问题描述

在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。

在这里插入图片描述

解决方法:并查集

在一棵树中,边的数量比节点的数量少 1。如果一棵树有 N 个节点,则这棵树有 N-1条边。这道题中的图在树的基础上多了一条附加的边,因此边的数量也是 N。
树是一个连通且无环的无向图,在树中多了一条附加的边之后就会出现环,因此附加的边即为导致环出现的边。可以通过并查集寻找附加的边
初始时,每个节点都属于不同的连通分量。遍历每一条边,判断这条边的两个顶点是否属于同一连通分量——即查看顶点的根节点是否相同

  • 不同,则两个顶点属于不同的连通分量。说明在遍历到当前边之前,这两个顶点之间不连通,因此当前的边不会导致环出现,合并这两个顶点的连通分量。

  • 相同,则两个顶点属于同一连通分量,则说明在遍历到当前的边之前,这两个顶点之间已经连通,因此当前的边导致环出现,为附加的边,将当前的边作为答案返回。

代码

class Solution {
    public int[] findRedundantConnection(int[][] edges) {
         int vertex = edges.length;

         //初始化并查集的父节点
         int[] parent  = new int[vertex+1];
         for (int i=1; i<=vertex; i++){  //注意:因为顶点编号从1开始,所以此处索引起点设置为1。
             parent[i] = i;
         }
         //定义一个list,保存所有会构成环的边(多余的边)
         ArrayList<int[]> list = new ArrayList<>();

         //遍历每条边
         for (int[] edge : edges){
            int node1 = edge[0];
            int node2 = edge[1];
            //找到边的两顶点的根节点
            int rootX = find(parent, node1);
            int rootY = find(parent, node2);
            //根节点不同,则表明该边的两个顶点位于不同联通分支
            if (rootX != rootY){
                 parent[find(parent, rootX)] = find(parent, rootY);
             }
            //根节点相同,则表明该边的两个顶点位于同一联通分支
            else{
                 list.add(edge);
             }
         }
        return list.get(list.size()-1);  //取出最后出现的边
    }
    
    //注意:find函数需要将父节点数组parent传过来
    public int find(int[] parent, int x){
        if (x != parent[x]){
            return find(parent, parent[x]);
        }
        else
            return parent[x];
    }
}

复杂度

时间复杂度:O(NlogN),其中 N 是图中的节点个数。需要遍历图中的 NN条边,对于每条边,需要查找其两个节点的根节点,如果两个节点的根节点不同则需要进行合并,需要进行 2 次查找和最多 1 次合并。一共需要进行 2N 次查找和最多 N 次合并,因此总时间复杂度是O(2NlogN)=O(NlogN)。这里的并查集使用了路径压缩,但是没有使用按秩合并,最坏情况下的时间复杂度是 O(NlogN),平均情况下的时间复杂度依然是 O(Nα(N)),其中 α 为阿克曼函数的反函数,α(N) 可以认为是一个很小的常数。

空间复杂度:O(N),其中 N 是图中的节点个数。使用数组 parent记录每个节点的父节点

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/redundant-connection/solution/rong-yu-lian-jie-by-leetcode-solution-pks2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值