[LeetCode] Redundant Connection II 冗余的连接之二
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents.
The given input is a directed graph that started as a rooted tree with N nodes (with distinct values 1, 2, ..., N), with one additional directed edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] that represents a directed edge connecting nodes u and v, where u is a parent of child v.
Return an edge that can be removed so that the resulting graph is a rooted tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array.
Example 1:
Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given directed graph will be like this:
1
/ \
v v
2-->3
Example 2:
Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]
Output: [4,1]
Explanation: The given directed graph will be like this:
5 <- 1 -> 2
^ |
| v
4 <- 3
Note:
- The size of the input 2D-array will be between 3 and 1000.
- Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.
这道题是之前那道 Redundant Connection 的拓展,那道题给的是无向图,只需要删掉组成环的最后一条边即可,归根到底就是检测环就行了。而这道题给的是有向图,整个就复杂多了,因为有多种情况存在,比如给的例子1就是无环,但是有入度为2的结点3。再比如例子2就是有环,但是没有入度为2的结点。其实还有一种情况例子没有给出,就是既有环,又有入度为2的结点。好,现在就来总结一下这三种情况:
第一种:无环,但是有结点入度为2的结点(结点3)
[[1,2], [1,3], [2,3]]
/ \
v v
-->
第二种:有环,没有入度为2的结点
[[1,2], [2,3], [3,4], [4,1], [1,5]]
<- ->
^ |
| v
<-
第三种:有环,且有入度为2的结点(结点1)
[[1,2],[2,3],[3,1],[1,4]]
/
v
/ ^
v \
-->
对于这三种情况的处理方法各不相同,首先对于第一种情况,返回的产生入度为2的后加入的那条边 [2, 3],而对于第二种情况,返回的是刚好组成环的最后加入的那条边 [4, 1],最后对于第三种情况返回的是组成环,且组成入度为2的那条边 [3, 1]。
明白了这些,先来找入度为2的点,如果有的话,那么将当前产生入度为2的后加入的那条边标记为 second,前一条边标记为 first。然后来找环,为了方便起见,找环使用联合查找 Union Find 的方法,可参见 Redundant Connection 中的解法三。当找到了环之后,如果 first 不存在,说明是第二种情况,返回刚好组成环的最后加入的那条边。如果 first 存在,说明是第三种情况,返回 first。如果没有环存在,说明是第一种情况,返回 second,参见代码如下:
class Solution {
public:
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
int n = edges.size();
vector<int> root(n + , ), first, second;
for (auto& edge : edges) {
if (root[edge[]] == ) {
root[edge[]] = edge[];
} else {
first = {root[edge[]], edge[]};
second = edge;
edge[] = ;
}
}
for (int i = ; i <= n; ++i) root[i] = i;
for (auto& edge : edges) {
if (edge[] == ) continue;
int x = getRoot(root, edge[]), y = getRoot(root, edge[]);
if (x == y) return first.empty() ? edge : first;
root[x] = y;
}
return second;
}
int getRoot(vector<int>& root, int i) {
return i == root[i] ? i : getRoot(root, root[i]);
}
};
讨论:使用联合查找 Union Find 的方法一般都需要写个子函数,来查找祖宗结点,上面的解法 getRoot() 函数就是这个子函数,使用递归的形式来写的,其实还可以用迭代的方式来写,下面这两种写法都可以:
int getRoot(vector<int>& root, int i) {
while (i != root[i]) {
root[i] = root[root[i]];
i = root[i];
}
return i;
}
int getRoot(vector<int>& root, int i) {
while (i != root[i]) i = root[i];
return i;
}
Github 同步地址:
https://github.com/grandyang/leetcode/issues/685
类似题目:
Number of Connected Components in an Undirected Graph
参考资料:
https://leetcode.com/problems/redundant-connection-ii/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Redundant Connection II 冗余的连接之二的更多相关文章
- [LeetCode] 685. Redundant Connection II 冗余的连接之二
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) f ...
- [LeetCode] 685. Redundant Connection II 冗余的连接之 II
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) f ...
- [LeetCode] Redundant Connection 冗余的连接
In this problem, a tree is an undirected graph that is connected and has no cycles. The given input ...
- LeetCode 685. Redundant Connection II
原题链接在这里:https://leetcode.com/problems/redundant-connection-ii/ 题目: In this problem, a rooted tree is ...
- [Swift]LeetCode685. 冗余连接 II | Redundant Connection II
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) f ...
- [LeetCode] Palindrome Permutation II 回文全排列之二
Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...
- [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- [LeetCode] Contains Duplicate II 包含重复值之二
Given an array of integers and an integer k, return true if and only if there are two distinct indic ...
- [LeetCode] Single Number II 单独的数字之二
Given an array of integers, every element appears three times except for one. Find that single one. ...
随机推荐
- Orcle查询优化改写-----给查询结果排序
1.按照子串排序 2.translate
- 键值编码KVC
动态设置:setValue:属性值 forKey:属性名用于简单路径:setValue:属性值 forKeyPath:属性路径用于复合路径,例如Person有一个Account类型的属性,那么pers ...
- 福州大学W班-助教总结
开学初对自己的期望 在即将到来的学期前,我希望我可以做到以下几点: 1.多参与同学的课程设计,并提出自己的见解 2.不断提高个人的专业技能,活到老学到老 3.能够及时对同学的博客进行评论,并给出有用的 ...
- Beta冲刺Day7
项目进展 李明皇 今天解决的进度 部分数据传递和使用逻辑测试 林翔 今天解决的进度 服务器端查看个人发布的action,修改已发布消息状态的action,仍在尝试使用第三方云存储功能保存图片 孙敏铭 ...
- java实现红包的分配算法
个人推测,微信红包在发出的时候已经分配好金额.比如一个10元的红包发给甲乙丙三个人,其实在红包发出去的时候,已经确定了第一个会领取多少,第二个会领取多少金额. 而不是在领取的时候才计算的.下面贴出实现 ...
- css中的em 简单教程 -- 转
先附上原作的地址: https://www.w3cplus.com/css/px-to-em 习惯性的复制一遍~~~~ -------------------------------我是分界线---- ...
- python之路--day11---迭代器和生成器
迭代: 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 为什么要有迭代器: 数据类型的取值,字符串,列表,元组依靠索引可以取值,但是字典,集合,文件这些数据类型无法 ...
- 什么是KMP算法?KMP算法推导
花了大概3天时间,了解,理解,推理KMP算法,这里做一次总结!希望能给看到的人带来帮助!! 1.什么是KMP算法? 在主串Str中查找模式串Pattern的方法中,有一种方式叫KMP算法 KMP算法是 ...
- node框架express
见识到原生nodeJs服务器的恶心后,我们来用下简单好用的框架吧~ 服务器无非主要提供接口和静态文件读取,直接上代码: const express = require('express'); cons ...
- Linux--初次体验
关于Linux已经听闻很久的大名了,但是一直没有机会来使用,这次趁着放假的机会,来体验一把Linux吧. 之前使用visuabox和Ubuntu16,但是虚拟机总是不能连接互联网,在虚拟机上面无法上网 ...