题目: 

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

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

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

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

示例:

      输入: [[1,2], [1,3], [2,3]]
      输出: [2,3]
      解释: 给定的有向图如下:
       1
       / \
      v v
      2-->3
      输入: [[1,2], [2,3], [3,4], [4,1], [1,5]]
      输出: [4,1]
      解释: 给定的有向图如下:
      5 <- 1 -> 2
       ^ |
       | v
       4 <- 3 题解:
  
在以上题目中有一句比较关键的句子 : 该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边
的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。

  这句话其实是引导我们思路的,我们可以知道题目所说的有根树具有三个性质。第一,有根树存在入度为0的节点(根节点),第二有根树除了
根节点其他节点的入度都为1。第三有根树所有节点都是连通的。
    如若一颗有根树加上一条边的话,那么加上的边存在以下三种情况:
    1)边的两端是同一节点
      判定方式 : 直接看两遍是否相等
      处理 : 直接可以知道这条边肯定不是原有的,返回当前边
    2)两端不是同一节点,并且被指向的是根节点。
      判定方式 : 如若被指向的那端统计之后出现了所有节点或者不存在入度为2的节点
      处理 : 因为根被指向了后一定会形成环,故而处理的可能性很多(除去环内任意边),但是需要注意是否存在示例2中的情况,如若除去边[1,5],就会导致该有根树不连通,并且依然有环。 因为是否连通使用并查集很容易检测是否连通
,故而这里我选择了直接使用并查集。
    3)两端不是同一节点,并且被指向的是非根节点。
      判定方式 : 剩下的情况都是3)//存在入度为2的节点
      处理 : 因为存在入度为2的节点,所以在这就是在两条指向入度为2节点内直接二选一,但是这里不能随便选,必须保证如若因为这条边成环(例如示例一加上一个节点4并且4指向2),也就是 : [[4, 2],[1,2], [1,3], [2,3]]
,这时指向2的一共有两个节点 4 和 1,这时候如若选择删除[1,2]则会导致整张图不连通,故而需要检查连通性来选择删除两个节点的哪个,依然使用并查集。
代码:
 int n;
public int[] findRedundantDirectedConnection(int[][] edges) {
this.n = edges.length;
int[] table = new int[n];
Arrays.fill(table, -1);
int other = -1;
for (int i = 0; i < n; i++) {
if (edges[i][0] == edges[i][1]) {
return edges[i];
}
int index = edges[i][1] - 1;
if (table[index] != -1) {
other = i;
} else {
table[index] = i;
}
}
// 如若指向非根
if (other != -1) {
// 且 如若删除了后面那个节点 仍然是 连通的。
if (this.isConnected(edges, other))
return edges[other];
else
return edges[table[edges[other][1] - 1]];
}
for (int i = n - 1; i >= 0; i--) {
//如若除去i还是连通的
if (this.isConnected(edges, i)) {
return edges[i];
}
}
return new int[] {};
} /**
* 若除去第i条边
*
* @param edges
* @param i
* @return
*/
int[] table; public boolean isConnected(int[][] edges, int i) {
this.table = new int[n];
for (int j = 0; j < n; j++) {
table[j] = j;
}
for (int j = 0; j < n; j++) {
if (j != i)
union(edges[j][0] - 1, edges[j][1] - 1);
}
boolean flag = true;
for (int k = 0; k < n; k++) {
if (table[k] == k) {
if (flag) {
flag = false;
} else {
return false;
}
}
}
return true;
} public boolean union(int i, int j) {
int iIndex = this.find(i);
int jIndex = this.find(j);
if (iIndex == jIndex) {
return false;
}
table[iIndex] = jIndex;
return true;
} public int find(int i) {
while (table[i] != i) {
i = table[i];
}
return i;
}
 

LeetCode 85. 冗余连接 II的更多相关文章

  1. Java实现 LeetCode 685 冗余连接 II(并查集+有向图)

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

  2. Leetcode 684.冗余连接

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

  3. Java实现 LeetCode 684 冗余连接(并查集)

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

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

  5. [Swift]LeetCode684. 冗余连接 | Redundant Connection

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

  6. Leetcode之并查集专题-684. 冗余连接(Redundant Connection)

    Leetcode之并查集专题-684. 冗余连接(Redundant Connection) 在本问题中, 树指的是一个连通且无环的无向图. 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2 ...

  7. LeetCode Single Number I / II / III

    [1]LeetCode 136 Single Number 题意:奇数个数,其中除了一个数只出现一次外,其他数都是成对出现,比如1,2,2,3,3...,求出该单个数. 解法:容易想到异或的性质,两个 ...

  8. [array] leetcode - 40. Combination Sum II - Medium

    leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...

  9. LeetCode 137. Single Number II(只出现一次的数字 II)

    LeetCode 137. Single Number II(只出现一次的数字 II)

随机推荐

  1. Kibana 7.1.1 安装及简单使用

    1. 下载 & 解压 # 下载 wget https://artifacts.elastic.co/downloads/kibana/kibana-7.1.1-linux-x86_64.tar ...

  2. 微服务-springboot-读写分离(多数据源切换)

    为什么需要读写分离 当项目越来越大和并发越来大的情况下,单个数据库服务器的压力肯定也是越来越大,最终演变成数据库成为性能的瓶颈,而且当数据越来越多时,查询也更加耗费时间,当然数据库数据过大时,可以采用 ...

  3. POJ 2728:Desert King(最优比率生成树)

    http://poj.org/problem?id=2728 题意:有n个点,有三个属性代表每个点在平面上的位置,和它的高度.点与点之间有一个花费:两点的高度差:还有一个长度:两点的距离.现在要让你在 ...

  4. 【原创】面试官:讲讲mysql表设计要注意啥

    引言 近期由于复习了一下mysql的内容,有些心得.随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且很多问题,都是面试中实打实会问到的! 比如 OK,具体 ...

  5. C++中 / 和 % 在分离各位时的妙用

    在学习c++的过程中,我们一般用 / 和 % 来分解数字的各个位 取整 (/) 比如1234 / 10 等于 123.4,这相当于把前三位分解出来了 取余(%) 比如 12345 的分解方法 个位:1 ...

  6. Protocol Buffer使用转换工具将proto文件转换成Java文件流程及使用

    Client与Server的网络通信协议传输使用google protobuf,服务器端使用的是Java 一. Protocol Buffersprotobuf全称Google Protocol Bu ...

  7. 走近Java之幕后的String

    前几天,有个同事问了我一个表面看起来显而易见的问题,是关于String的,我们一起来看一下(如果有说的不正确的地方,欢迎大家指正). java中,字面量在编译期计算,并且String字面量作为常量,存 ...

  8. C++ 编程技巧锦集(一)

    C++刷题精髓在STL编程,还有一些函数.下面我就总结一下本人在刷题过程中,每逢遇见总要百度的内容………………(大概率因为本人刷题太少了) 1. map map<string, int> ...

  9. 【动态规划例题-数塔问题】-C++

    描述 观察下面的数字金字塔.写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以 从当前点走到左下方的点也可以到达右下方的点. 在上面的样例中,从13到8到26到15到24 ...

  10. ASP.NET CORE配置用户密码验证

    在 class Startup 中配置 public void ConfigureServices(IServiceCollection services) { services.AddDbConte ...