685. 冗余连接 II

685. 冗余连接 II

原题链接:

685. 冗余连接 II

https://leetcode.cn/problems/redundant-connection-ii/description/

完成情况:

解题思路:

java 复制代码
在这里插入代码片

参考代码:

java 复制代码
package 代码随想录.并查集;

import java.util.ArrayList;

public class _685冗余连接II {
    int N_node = 1002;
    int fatherPaths [] ;

    public _685冗余连接II() {
        fatherPaths = new int[N_node];
        //并查集初始化
        for (int i = 0; i < N_node; i++){
            fatherPaths[i] =  i;
        }
    }

    /**
     * 有向图形成输,然后去除掉节点,存在多个 节点则删除掉最后一个节点
     * @param edges
     * @return
     */
    public int[] findRedundantDirectedConnection(int[][] edges) {
        //这次主要是多了一个方向,构造父亲节点,寻根的时候要考虑方向问题
        int [] inDegree = new int[N_node];  //记录入度边
        for (int i = 0;i< edges.length;i++){
            //入度边
            inDegree[edges[i][1]] += 1;
        }
        //找出入度为 2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
        ArrayList<Integer> twoInDegree = new ArrayList<Integer>();  //注意要重点留意那些有多个入度的边,因为如果只有一个节点的话,你删除掉了那个节点,那么就会导致出现单节点,就无法构成一颗树
        for (int i = edges.length - 1;i>=0;i--){
            if (inDegree[edges[i][1]] == 2){    //只要大于1条边就记录下来
                twoInDegree.add(i);
            }
        }

        //处理图中情况1 和情况2
        //如果有入度为2的节点,那么一定是两条边里删除一个,看看删哪个可以构成树
        if (!twoInDegree.isEmpty()){
            if (isTreeAfterRemoveEdge(edges,twoInDegree.get(0))){
                return edges[twoInDegree.get(0)];
            }
            return edges[twoInDegree.get(1)];
        }

        //明确没有入度大于2的情况了,那么一定有有向环,找到构成环的边返回就可以了
        if (!twoInDegree.isEmpty()){
            if (isTreeAfterRemoveEdge(edges,twoInDegree.get(0))){
                return edges[twoInDegree.get(0)];
            }
            return edges[twoInDegree.get(1)];
        }

        //明确没有入度为2的情况,那么 一定有有向环,找到构成环的边返回就可以了
        return getRemoveEdge(edges);
    }

    /**
     * 在有向图里找到删除的那条边,使其变成树
     * @param edges
     * @return 要删除的边
     */
    private int[] getRemoveEdge(int[][] edges) {
        initFatherPath();
        for (int i = 0; i < edges.length; i++) {
            if (sameEdge(edges[i][0], edges[i][1])){    //构成 有向环了,就删除要删除的边
                return edges[i];
            }
            joinEdge(edges[i][0],edges[i][1]);
        }
        return null;
    }

    /**
     *
     * @param edgeA
     * @param edgeB
     */
    private void joinEdge(int edgeA, int edgeB) {
        edgeA = fatherPaths[edgeA];
        edgeB = fatherPaths[edgeB];
        if (edgeA == edgeB) return;
        fatherPaths[edgeB] = edgeA; //     A -> B
    }

    /**
     *
     * @param edgeA
     * @param edgeB
     * @return
     */
    private boolean sameEdge(int edgeA, int edgeB) {
        edgeA = fatherPaths[edgeA];
        edgeB = fatherPaths[edgeB];
        return edgeB == edgeA;
    }

    /**
     *
     */
    private void initFatherPath() {
        //并查集初始化
        for (int i =0;i<N_node;++i){
            fatherPaths[i] = i;
        }
    }

    /**
     * 删一条边之后判断是不是树
     * @param edges
     * @param deleteEdge 要删除的边
     * @return  true: 是树, false: 不是树
     */
    private boolean isTreeAfterRemoveEdge(int[][] edges, int deleteEdge) {
        initFatherPath();
        for (int i = 0; i < edges.length;i++){
            if (i == deleteEdge)    continue;
            if (sameEdge(edges[i][0],edges[i][1])){ //构成有向环了,一定不是树
                return false;
            }
            joinEdge(edges[i][0],edges[i][1]);
        }
        return true;
    }
}

错误经验吸取

相关推荐
库库林_沙琪马1 小时前
Redis 持久化:从零到掌握
数据库·redis·缓存
paterWang1 小时前
基于 Python 和 OpenCV 的酒店客房入侵检测系统设计与实现
开发语言·python·opencv
东方佑1 小时前
使用Python和OpenCV实现图像像素压缩与解压
开发语言·python·opencv
我真不会起名字啊2 小时前
“深入浅出”系列之杂谈篇:(3)Qt5和Qt6该学哪个?
开发语言·qt
laimaxgg2 小时前
Qt常用控件之单选按钮QRadioButton
开发语言·c++·qt·ui·qt5
牵牛老人2 小时前
Qt中使用QPdfWriter类结合QPainter类绘制并输出PDF文件
数据库·qt·pdf
水瓶丫头站住2 小时前
Qt的QStackedWidget样式设置
开发语言·qt
尼尔森系4 小时前
排序与算法:希尔排序
c语言·算法·排序算法
小钊(求职中)4 小时前
Java开发实习面试笔试题(含答案)
java·开发语言·spring boot·spring·面试·tomcat·maven
卡西里弗斯奥4 小时前
【达梦数据库】dblink连接[SqlServer/Mysql]报错处理
数据库·mysql·sqlserver·达梦