684 冗余连接

684 冗余连接

在这里插入图片描述
在这里插入图片描述

并查集-01

class Solution {
    
   public int[] findRedundantConnection(int[][] edges) {
        int n=edges.length;
        int[] father=new int[n+1];
        int i=n-1;
        for(;i>0;i--){
            if(findNum(edges,father,i,n)==1){
                break;
            }
        }
        return edges[i];
    }
    public int findNum(int[][] edges,int[] father,int len,int n){
        int counts=0;
        for(int i=1;i<=n;i++){
            father[i]=i;
        }

        for(int i=n-1;i>=0;i--){
            if(i==len){
                continue;
            }
            union(father,edges[i][0],edges[i][1]);
        }
        for(int i=1;i<=n;i++){
            if(father[i]==i){
                counts++;
            }
        }
        return counts;
    }
    public int find (int[] father,int a){
    //路径压缩:把沿途的每个节点的父节点都设为根节点
        if(father[a]!=a){
            father[a]=find(father,father[a]);
        }
        return father[a];
    }
    public void union(int[] father,int a,int b){
    	//合并操作:先找到两个集合的代表元素,然后将前者的父节点设为后者即可。
        //a的父节点是b
        father[find(father,a)]=find(father,b);
    }

}

在这里插入图片描述
时间复杂度 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn)
空间复杂度 O ( n ) O(n) O(n)

并查集-02

树是一个连通且无环的无向图,在树中多了一条附件的边之后就会出现环,因此附加的边就是导致环出现的边。
可以通过并查集寻找附加的边。初始时,每个节点都属于不同的连通分量。遍历每一条边,判断这条边连接的两个顶点是否属于相同的连通分量。

  • 如果两个顶点属于不同的连通分量,则说明在遍历到当前的边之前,这两个顶点之间不连通,因此当前的边不会导致环出现,合并这两个顶点的连通分量。
  • 如果两个顶点属于相同的连通分量,则说明在遍历到当前的边之前,这两个顶点之间已经连通,因此当前的边导致环出现,为附加的边,将当前的边作为答案返回。
class Solution {
    
   public int[] findRedundantConnection(int[][] edges) {
        int n=edges.length;
        int[] father=new int[n+1];
        int i=0;
        for(int j=1;j<=n;j++){
            father[j]=j;
        }
        for(;i<n;i++){
            if(find(father,edges[i][0])!=find(father,edges[i][1])){
                //未连通
                //则合并
                union(father,edges[i][0],edges[i][1]);
            }else{
                break;
            }
        }
        return edges[i];
    }
    
    public int find (int[] father,int a){
        if(father[a]!=a){
            father[a]=find(father,father[a]);
        }
        return father[a];
    }
    public void union(int[] father,int a,int b){
        //a的父节点是b
        father[find(father,a)]=find(father,b);
    }

}

在这里插入图片描述
时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),其中 n n n是图中的节点个数。需要遍历图中的 n n n条边,对于每条边,需要对两个节点找祖先,如果两个节点的祖先不同则需要进行合并,需要进行 2 2 2次查找和最多 1 1 1次合并。一共需要进行 2 n 2n 2n次查找和最多 n n n次合并。
空间复杂度 O ( n ) O(n) O(n)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值