Skip to content

Commit aad4e44

Browse files
Merge branch 'master' of https://github.com/apachecn/LeetCode
2 parents c3b4b27 + e6e5a48 commit aad4e44

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
### 685. Redundant Connection II
2+
3+
题目:
4+
<https://leetcode.com/problems/redundant-connection-ii/>
5+
6+
7+
难度 : Hard
8+
9+
10+
11+
我们先定义一下,每条边的第一个点是parent,第二个点是child,例如 2 -> 1 中 node 2 就是 parent,而 node 1 就是 child
12+
13+
明确这个之后,我们要知道图中有一条边是 invalid 的,去除它之后整个图就变成了一棵树,那么什么情况下一个边会导致树变成图呢:
14+
15+
1. 如果一个child 在此之前已经有过一个parent了,那么意味着它有两个parent,这在树中肯定是不合法的。
16+
在代码中体现为```node_parent[child] != child```,这说明在碰到此时的parent之前我们就已经更新过node_parent[child]了,即child之前已经有一个parent了
17+
2. 如果一个child 的 parent 的 parent(或者一直往上找) 就是 child 本身,那么这意味着有环,这在树中也肯定是不合法的。
18+
在代码中体现为```find(node_parents, parent) == child```, 这说明child的parent的parent或以上就是child本身,即有环。
19+
例如 ```1 --> 2 --> 1```或者```1 --> 2 --> 3 --> 1```
20+
21+
因此我们可以定义一个列表 node_parent,在最开始的时候,此列表的 index 和 value 一一相等。
22+
23+
然后我们对edges进行第一轮遍历(正序遍历),并且用count来计数不合法的边:
24+
- 如果只找到一条不合法的边,那么直接返回它即可
25+
- 如果有超过一条不合法的边,那么我们就进行第二轮遍历(逆序遍历),返回碰到的第一条不合法的边,
26+
这里是为了节约时间,因为如题意我们要返回的是最后一条出现的边,那么我们逆序就更省时间嘛
27+
28+
29+
```python
30+
class Solution(object):
31+
def findRedundantDirectedConnection(self, edges):
32+
"""
33+
:type edges: List[List[int]]
34+
:rtype: List[int]
35+
"""
36+
37+
def find(node_parent, parent):
38+
return parent if node_parent[parent] == parent else find(node_parent, node_parent[parent])
39+
40+
n, count = len(edges), 0 # 用 count 来计数不合法的边
41+
node_parent = [i for i in range(n+1)]
42+
res = [0, 0]
43+
44+
# 第一轮查找不合法的边 (正序)
45+
for i in range(n):
46+
parent, child = edges[i][0], edges[i][1]
47+
if node_parent[child] != child or find(node_parent, parent) == child:
48+
res = edges[i]
49+
count += 1
50+
else:
51+
node_parent[child] = parent
52+
if count == 1: # 如果只有一条不合法的边,直接返回
53+
return res
54+
55+
# 重置 node_parent 并开始第二轮查找 (逆序)
56+
node_parent = [i for i in range(n+1)]
57+
for i in range(n-1, -1, -1):
58+
parent, child = edges[i][0], edges[i][1]
59+
if node_parent[child] != child or find(node_parent, parent) == child:
60+
return edges[i]
61+
else:
62+
node_parent[child] = parent
63+
return res
64+
```
65+
这道题感谢[xyzxuyizhen](https://leetcode.com/problems/redundant-connection-ii/discuss/128596/Easy-to-understand-Java-Solution-Union-Find)大佬,
66+
看到他的思路才逃离了我之前的很复杂的想法。

0 commit comments

Comments
 (0)