当前位置: 首页 > article >正文

LeetCode每日一题685---冗余连接 II

一、题目描述

在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。

输入一个有向图,该图由一个有着 n 个节点(节点值不重复,从 1 到 n)的树及一条附加的有向边构成。附加的边包含在 1 到 n 中的两个不同顶点间,这条附加的边不属于树中已存在的边。

结果图是一个以边组成的二维数组 edges 。 每个元素是一对 [ui, vi],用以表示 有向 图中连接顶点 ui 和顶点 vi 的边,其中 uivi 的一个父节点。

返回一条能删除的边,使得剩下的图是有 n 个节点的有根树。若有多个答案,返回最后出现在给定二维数组的答案。

示例 1:
在这里插入图片描述

输入:edges = [[1,2],[1,3],[2,3]]
输出:[2,3]

示例 2:
在这里插入图片描述

输入:edges = [[1,2],[2,3],[3,4],[4,1],[1,5]]
输出:[4,1]

提示:
n == edges.length
3 <= n <= 1000
edges[i].length == 2
1 <= ui, vi <= n

二、解题思路

这道题目与冗余连接 I一样需要用到并查集,但是要分三种情况:

  • 情况一:入度为2,部分成环
  • 情况二:入度为2,不成环
  • 情况三:入度全为1,只能成环

对于情况一和情况二,一定是删除指向入度为2的节点的两条边其中的一条,如果删了一条,判断这个图是一个树,那么这条边就是答案,同时注意要从后向前遍历,因为如果两天边删哪一条都可以成为树,就删最后那一条。
在这里插入图片描述

对于情况三,明确没有入度为2的情况,那么一定有向环,找到构成环的边就是要删除的边。
在这里插入图片描述

三、代码

// 并查集找父结点
 int find(int parent[],int x){
    if(x == parent[x]){
        return x;
    }else{
        parent[x] = find(parent,parent[x]);
        return parent[x];
    }
 }

// 对于情况一和情况二判断要删除那条边
bool isTreeAfterRemoveEdge(int** edges,int edgeSize,int deleteEdge){

    //初始化并查集
    int parent[edgeSize+1];
    for(int i=0;i<=edgeSize;i++){
        parent[i] = i;
    }
    int root1,root2;
    for(int i=0;i<edgeSize;i++){
        if (i == deleteEdge) continue;  // 跳过要删除的边
        root1 = find(parent,edges[i][0]);
        root2 = find(parent,edges[i][1]);
        if(root1 == root2){
            return false;
        }

        parent[root1] = root2;
    }
    
    return true;
}

//  情况三,找到构成环的边就是要删除的边。
int  getRemoveEdge(int** edges,int edgeSize){
     //初始化并查集
    int parent[edgeSize+1];
    for(int i=0;i<=edgeSize;i++){
        parent[i] = i;
    }
     int root1,root2;
     for(int i=0;i<edgeSize;i++){
        root1 = find(parent,edges[i][0]);
        root2 = find(parent,edges[i][1]);
        if(root1 == root2){
            return i;
        }
        parent[root1] = root2;
     }

     return -1;


}

int* findRedundantDirectedConnection(int** edges, int edgesSize, int* edgesColSize, int* returnSize) {

    // 计算每一个结点的入度
    int inDefree[1010]={0};
    *returnSize = 2;
    
    for(int i=0;i<edgesSize;i++){
        inDefree[edges[i][1]]++;
    }
    //   记录入度为2的边(如果有的话就两条边)
    // 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案
    int *array = (int *)malloc(sizeof(int) *2);
    int k=0;
    for(int i = edgesSize-1;i>=0;i--){
        if(inDefree[edges[i][1]]==2){
            array[k++] = i;
        }
    }

     // 如果有入度为2的节点,那么一定是两条边里删一个,看删哪个可以构成树
     if(k>0){
        if(isTreeAfterRemoveEdge(edges,edgesSize, array[0])){
            return edges[array[0]];
        }else{
            return edges[array[1]];
        }
     }


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

     int res = getRemoveEdge(edges,edgesSize);

     return edges[res];
    
}

http://www.kler.cn/a/375727.html

相关文章:

  • SmartX 在新能源:支撑多家头部企业 MES 等核心系统稳定运行与 VMware 替换
  • 补齐:相交链表:扣160
  • windows@命令行中获取环境变量取值不展开取值(原值)
  • 从0开始的STM32学习之旅:使用中断完成等待型任务(理论部分)
  • Java避坑案例 - 线程池未复用引发的故障复盘及源码分析
  • FastAPI新手系列:教你如何合理规划和复用Model,写出优雅的API
  • [MySQL#10] 索引底层(1) | Page | 页目录
  • MCU内存结构解析:FLASH、ROM与RAM的功能与区别
  • elasticsearch 8.x 插件安装(六)之Hanlp插件
  • 超萌!HTMLCSS:超萌卡通熊猫头
  • 中仕公考:上海市25年公务员考试今日报名
  • 【开源免费】基于SpringBoot+Vue.JS网上租赁系统(JAVA毕业设计)
  • 网络通信与并发编程(八)I/O模型
  • 重学前端 File、Blob、FileReader 基础知识学习
  • 4、片元着色器之光线步进及其和兰伯特光照模型的结合应用
  • ChatGPT网页正式上线搜索聊天记录功能!埃隆马斯克的xAI正试图筹集数十亿美元|AI日报
  • ctfshow--xss靶场web327-web333(一命速通不了的靶场)
  • 小程序与服务器通信webSocket和UDPSocket
  • 【Java】异常处理见解,了解,进阶到熟练掌握
  • Github上的十大RAG(信息检索增强生成)框架
  • web——upload1——攻防世界
  • JBoss 6.x中间件监控指标详解
  • 《Python游戏编程入门》注-第4章6
  • C# 图片工具类,缩略图、加水印、调整光暗和灰度、翻转图片等...
  • npm入门教程1:npm简介
  • django重写响应对象