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

685. 冗余连接 II

力扣刷题记录

并查集 有向图

685. 冗余连接 II

思路

对于这道困难题,并没有思路
从昨天的无向图变为今天的有向图,题目从中等升级到了困难

因此需要同时记录上一级连接的节点和使用并查集
树中所有入度除了一个为0 其它的为1
记录上一级的节点是为了判断是否存在冲突的边,即这个点存在两个入度
因此记录这一条冲突的边

否则判断这条边是否会形成环路
通过加入并查集 进行判断 成环了 记录下来

最后如果没有冲突的边 跟昨天一样 返回最后标记成环的边即可

否则

有冲突的边 假设为 [u, v] 此时肯定得返回 [u, v] 或者 [parents[v], v] 中的一条(为了保证入度正常)

没有成环的边 返回冲突的边 [u, v]即可

如果既有冲突的边, 也有成环的边,成环的边不可能是[u, v] 因为已经被标记了,不会进入成环的监测再进行标记, 因此直接 返回 另外一条边 [parents[v], v] 即可 (不一定返回最后标记的成环那一条边,因为一个环中的另外一条边[parents[v], v] 需要返回 才能同时去掉环和存在入度异常的点

代码
func find(ancestor []int, x int) int{
    if ancestor[x] != x{
        ancestor[x] = find(ancestor, ancestor[x])  // 路径压缩  只保留最根的节点
        // return find(ancestor, ancestor[x]) // 不进行路径压缩
    }
    return ancestor[x]
}

func findRedundantDirectedConnection(edges [][]int) []int {

    var parents []int = make([]int, len(edges) + 1) // 记录上一级父节点
    var ancestor []int = make([]int, len(edges) + 1) // 记录最上面的祖先节点   并查集
    for i := 0; i < len(edges) + 1 ; i++{
        parents[i] = i
        ancestor[i] = i
    }

    conflict := -1
    cycle := -1
    for i, edge := range edges{
        from := edge[0]
        to := edge[1]

        if parents[to] != to{
            // 该点 已经在一条边中加入了 已经有一个入度了
            conflict = i
        }else{
            parents[to] = from

            m := find(ancestor, from)
            n := find(ancestor, to)

            if m == n{
                // 成环了
                cycle = i
            }else{
                ancestor[m] = n
            }
        }
    }

    if conflict < 0{
        // 和昨天的一样,返回成环的边即可
        return edges[cycle]
    }else{
        to := edges[conflict][1]
        if cycle >= 0{
            var res []int = make([]int, 2)
            res[0] = parents[to]
            res[1] = to
            return res
        }else{
        	// 没有成环的 返回 冲突的边即可
            return edges[conflict]
        }
    }
}

时间复杂度:O(n*logn)
空间复杂度:O(n)


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

相关文章:

  • 扫盲(索引存储)
  • 设计模式-单例模型(单件模式、Singleton)
  • member access within null pointer of type ‘ListNode‘
  • 代码随想录 -- 动态规划 -- 使用最小花费爬楼梯
  • Ubuntu22.04环境搭建MQTT服务器
  • 什么是Kubernetes?K8s基础与工作原理
  • [LeetCode] 784. 字母大小写全排序
  • 聚合值和非聚合值比较【SQL】
  • 基于SpringBoot的高考志愿智能推荐系统的设计与实现
  • Stable diffusion inference 多卡并行
  • FAQ-为什么交换机发给服务器的日志显示的时间少8小时
  • 易考八股文之如何对数据库进行优化(优化不少于十条)
  • 【学术会议论文投稿】“从零到一:使用IntelliJ IDEA打造你的梦幻HTML项目“
  • Android 原生开发与Harmony原生开发浅析
  • 压缩传感革命——自动验证算法证明了神经网络的准确性
  • ETL、ELT和反向ETL都有什么不同?怎么选择?
  • 基于vue框架的的高校学生资助信息系统3b240(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • Linux服务器自动化批量安装IB网卡驱动
  • Git - 如何删除 push 过一次的文件链路追踪?
  • autMan奥特曼机器人-实时翻译的用法
  • 常用 SQL 语句的大全
  • Mybatis高级
  • Android13、14特殊权限-应用安装权限适配
  • Django-中间件(切面编程AOP)
  • 设计模式(二)
  • cjson内存泄漏问题注意事项