题目描述

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

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

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

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

示例1

        输入:
[[1,2], [1,3], [2,3]]
输出:
[2,3]
解释:1/ \
v   v
2-->3

示例2

        输入:
[[1,2], [2,3], [3,4], [4,1], [1,5]]
输出:
[4,1]
解释:
5 <- 1 -> 2^    ||    v4 <- 3

提示

  • 输入的二维数组大小在
  • 二维数组中的整数在 之间,其中 是输入数组的大小。

题解

这题是上一道题LeetCode 685. 冗余连接的进阶版,区别就是无向图变成了有向图。

上一道题解说过,无向图能构成一棵树的条件是没有环,那么有向图的条件是什么呢?

首先还是得没有环,其次因为是边是有向的,所以一个结点只能有一个父结点(也就是入度为 )。那么这题解法就有了。

  • 首先判断有没有入度为 的结点,如果有的话,那两条边一定有一条得删掉。
  • 按照出现时间从后到前看那两条边,删掉其中一条之后是否能构成一棵树(也就是无环)。如果删掉了无环,那就直接返回这条边作为答案。
  • 如果入度全是 ,那就直接按照出现时间从前到后看添加了哪一条边之后开始出现了环,那么那条边就是答案。

判断能否构成一棵树的话还是用并查集,唯一区别就是不需要用按秩合并的优化了,而且给定有向边 ,只能把 接在 下面。

代码

c++

        class Solution {public:static const int N = 1010;int f[N], degree[N];int n;vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {n = edges.size();memset(degree, 0, sizeof degree);for (auto e : edges) ++degree[e[1]];for (int i = n-1; i >= 0; --i) {if (degree[edges[i][1]] == 2 && !wrongEdge(edges, i).size()) {return edges[i];}}return wrongEdge(edges, n);}vector<int> wrongEdge(vector<vector<int>>& edges, int except) {init();for (int i = 0; i < n; ++i) {if (i == except) continue;int u = edges[i][0], v = edges[i][1];if (same(u, v)) return edges[i];join(u, v);}return {};}void init() {for (int i = 1; i <= n; ++i) {f[i] = i;}}int find(int u) {return u==f[u] ? u : f[u]=find(f[u]);}void join(int u, int v) {u = find(u);v = find(v);if (u == v) return;f[v] = u;}bool same(int u, int v) {u = find(u);v = find(v);return u == v;}
};

python

        class Solution:def findRedundantDirectedConnection(self, edges: List[List[int]]) -> List[int]:self.n = len(edges)degree = [0] * (self.n+1)for u, v in edges:degree[v] += 1for u, v in edges[::-1]:if degree[v] == 2 and len(self.wrongEdge(edges, [u, v])) == 0:return [u, v]return self.wrongEdge(edges, [])def wrongEdge(self, edges, ex):self.f = [i for i in range(self.n+1)]for u, v in edges:if [u, v] == ex:continueif self.same(u, v):return [u, v]self.join(u, v)return []def find(self, u):if u == self.f[u]:return uself.f[u] = self.find(self.f[u])return self.f[u]def join(self, u, v):u, v = self.find(u), self.find(v)if u == v:returnself.f[v] = udef same(self, u, v):u, v = self.find(u), self.find(v)return u == v

每日算法系列【LeetCode 685】冗余连接 II相关推荐

  1. LeetCode 685. 冗余连接 II(并查集)

    1. 题目 在本问题中,有根树指满足以下条件的有向图.该树只有一个根节点,所有其他节点都是该根节点的后继. 每一个节点只有一个父节点,除了根节点没有父节点. 输入一个有向图,该图由一个有着N个节点 ( ...

  2. LeetCode 685. 冗余连接 II

    文章目录 解法1:并查集 https://leetcode-cn.com/problems/redundant-connection-ii/ 难度:困难   在本问题中,有根树指满足以下条件的有向图. ...

  3. Leetcode 685. 冗余连接 II Redundant Connection II

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

  4. LeetCode 684. 冗余连接(并查集)

    1. 题目 在本问题中, 树指的是一个连通且无环的无向图. 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, -, N) 的树及一条附加的边构成.附加的边的两个顶点包含在1到N中间,这条附 ...

  5. 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符

    题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...

  6. 每日算法刷题Day5-平方矩阵II和III、蛇形矩阵图解

    ⭐每日算法题解系列文章旨在精选重点与易错的算法题,总结常见的算法思路与可能出现的错误,与笔者另一系列文章有所区别,并不是以知识点的形式提升算法能力,而是以实战习题的形式理解算法,使用算法.

  7. 求栈中元素个数算法_每日算法系列【LeetCode 315】计算右侧小于当前元素的个数...

    题目描述 给定一个整数数组 nums ,按要求返回一个新数组 counts .数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量. 示例 ...

  8. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

  9. 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 523】连续的子数组和...

    题目描述 给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数. 示例1 输入: [ ...

  10. 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 330】按要求补齐数组...

    题目描述 给定一个已排序的正整数数组 nums ,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的 ...

最新文章

  1. Spring Cloud Alibaba 系统保护 - 限流与熔断:Sentinel 在项目中的最佳实践
  2. Renascence架构原理——遗传规划算法
  3. Pycharm打包生成exe可执行文件
  4. 多线程编程之四——线程的同步
  5. 华为手机连接电脑显示无法连接服务器,无法连接到服务器电脑
  6. 牛客挑战赛53G-同源数组(Easy Version)【NTT】
  7. python 导入数据对不齐_[Python] 大文件数据读取分析
  8. 这50个思维方法,深刻改变了我的人生
  9. Winform程序多种语言切换
  10. Python — sklearn 分类效果评估
  11. 小程序源码:聊天斗图微信表情包
  12. javascript设置颜色值的几种方法
  13. uva 10859 放置街灯树形dp
  14. vue3需要注意的小问题
  15. Flutter系列之在 macOS 上安装和配置 Flutter 开发环境
  16. Linux如何测试驱动性能,掌握 Linux PC 性能之基准测试
  17. 基于 ocr 的屏幕文字识别 开源
  18. 感冒发烧,病毒,细菌,抗生素?
  19. 计算机网络课程实训方法,中职学校计算机网络实训课教学初探
  20. 数据库——MySQL(一)(数据库常用命令、数据类型、创建表与修改表结构、约束、约束修改添加)

热门文章

  1. 5. DOM解析XML
  2. SharePoint 2013 中的新增功能(与开发有关)
  3. 在ubuntu下安装MonoDevelop
  4. 【排序算法】选择排序
  5. java day18【线程池、Lambda表达式】
  6. yum安装mysql5.7
  7. iOS_SN_详解沙河(转载)
  8. 超大数据量操作 java程序优化[转载]
  9. javascript模拟抽奖
  10. 人工智能与深度学习实战(4)——口罩佩戴识别(CNN)