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

类似题目:

Redundant Connection

Friend Circles

Accounts Merge

Number of Islands II

Graph Valid Tree

Number of Connected Components in an Undirected Graph

Similar String Groups

参考资料:

https://leetcode.com/problems/redundant-connection-ii/

https://leetcode.com/problems/redundant-connection-ii/discuss/108045/C++Java-Union-Find-with-explanation-O(n)

https://leetcode.com/problems/redundant-connection-ii/discuss/108058/one-pass-disjoint-set-solution-with-explain

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 685. Redundant Connection II 冗余的连接之二的更多相关文章

  1. [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 ...

  2. [LeetCode] Redundant Connection II 冗余的连接之二

    In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) f ...

  3. LeetCode 685. Redundant Connection II

    原题链接在这里:https://leetcode.com/problems/redundant-connection-ii/ 题目: In this problem, a rooted tree is ...

  4. [LeetCode] 684. Redundant Connection 冗余的连接

    In this problem, a tree is an undirected graph that is connected and has no cycles. The given input ...

  5. [LeetCode] Number of Islands II 岛屿的数量之二

    A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...

  6. LN : leetcode 684 Redundant Connection

    lc 684 Redundant Connection 684 Redundant Connection In this problem, a tree is an undirected graph ...

  7. [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 ...

  8. LeetCode 684. Redundant Connection 冗余连接(C++/Java)

    题目: In this problem, a tree is an undirected graph that is connected and has no cycles. The given in ...

  9. leetcode 684. Redundant Connection

    We are given a "tree" in the form of a 2D-array, with distinct values for each node. In th ...

随机推荐

  1. kudu 查看元数据信息

    package com.lala.lala.pipe.dbinfo import org.apache.kudu.client.KuduClient import com.lala.lala.comm ...

  2. 迷你版mybatis

    public class BootStrap { public static void start(){ MySqlSession sqlSession = new MySqlSession();// ...

  3. git 给分支添加描述 管理分支实用方法

    1.背景 在我们工作中,正常情况我们处在一个迭代中,一个人最多会有几个功能,比较正常的操作我们会给每个大功能创建不同的分支,方便管理. 我们可以非常愉快的进行版本管理,遇到特殊情况我们也可以方便版本退 ...

  4. jre、jdk、jvm之间的关系

    很多Java的程序员在写了很多代码之后,你问他JRE和JDK是是什么关系,JVM又是什么东西,他是不知道的. JVM(Java Virtual Machine) Java 虚拟机.它只认识 xxx.c ...

  5. Zabbix邮件预警-这个坑我跳了不止一次

    文章 Github 地址:点我 每每碰到 Zabbix,我发现配置邮件预警这个坑,我必须要跳进去,跟它是有八辈子的仇哦,哎,接下来数数这些坑.看看你遇到过类似的吗? Zabbix 预警配置流程 监控项 ...

  6. 【spring】全局异常 globalexception 处理

    全局异常 globalexception 处理   一般在做api开发时我们希望将所有业务层抛到controller异常都集中处理一下.比如对异常差异化报警.转发不同页面.封装不同http状态码.集中 ...

  7. PHP 数组函数大全

    PHP数组函数是核心的一部分.无需安装即可使用这些函数 函数名称 描述 array_change_key_case 将数组中的所有键名修改为全大写或小写 array_chunk 将一个数组分割成多个 ...

  8. OC编码规范

    http://www.jianshu.com/p/8b76814b3663#class-constructor-methods

  9. 汇编指令之JMP,CALL,RET(修改EIP的值!!!)

    简单介绍了,JMP指令按市面上的意思来说是跳转到指定地址,但我这里不这么说,JMP, CALL, RET三个指令均为修改EIP值的指令,EAX, ECX, EBX, EDX, ESP, EBP, ES ...

  10. ajax的jQuery的表单序列化获取参数serialize()

    需要引入jQuery.js才能使用$("form表单的id").serialize()可获取form表单里面所有表单元素的值和name属性值,按顺序拼接成查询字符串格式为name值 ...