[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. ...
随机推荐
- 【最全】经典排序算法(C语言)
算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...
- 一次精疲力尽的改bug经历
一.介绍 最近一直在做有关JavaScriptCore的技术需求,上周发现一个问题,当在JavaScriptCore在垃圾回收时,项目会有一定几率发生崩溃.崩溃发生时调用堆栈如下: 图1 调用堆栈 先 ...
- iptables.sh 初始化防火墙配置
#!/bin/bash iptables -F iptables -X iptables -Z iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT ...
- 计算1-1/3+1/5-1/7+···的前n项和
这图1为书里的教材,图二为自己打的程序 (1)二者相比,自己写的代码显得更短,听说代码写的越精简越好,但是自己的较难分析,他人看来可能会较难理解一点:(自己在第一次运行时将for()中的第二个表达式写 ...
- 【Redis使用系列】redis设置登陆密码
找到安装redis的配置文件,找到redis.comf文件找到#requirepass foobared 新建一行 requirepass xxxx 你的密码 ,然后重启.再登录的时候可以登录,但是 ...
- %f使用时的注意事项
1不是所有定义都用int,使用浮点函数需要把int改成float才能正常工作 2保留一位小数时要打入%0.1f,保留两位小数时要打入%0.2f,而不是%0.01f
- 福州大学W班 软件工程课中期调查
问卷地址:https://www.wjx.cn/jq/17054810.aspx
- Beta No.2
今天遇到的困难: 组员对github极度的不适应 Android Studio版本不一致项目难以打开运行 移植云端的时候,愚蠢的把所有项目开发环境全部搬上去.本身云的内存小,性能差,我们花费了太多时间 ...
- Beta冲刺Day6
项目进展 李明皇 今天解决的进度 进行前后端联动调试 明天安排 完善程序运行逻辑 林翔 今天解决的进度 服务器端发布消息,删除消息,检索消息,个人发布的action 明天安排 图片功能遇到问题,微信小 ...
- SOAP不同版本引起的问题
曾经遇到这样一个问题,在组织soap字符串时报这个错误: 2013-5-29 17:25:56 org.apache.cxf.phase.PhaseInterceptorChain doDefaul ...