代码随想录算法训练营
力扣684.冗余连接【medium】
力扣.冗余连接Ⅱ【hard】
一、力扣684.冗余连接【medium】
题目链接:力扣684.冗余连接
left =x300
视频链接:代码随想录
题解链接:灵茶山艾府
1、思路
-
可以从前向后遍历每一条边(因为优先让前面的边连上),边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点)。
- 如图所示,节点A 和节点 B 不在同一个集合,那么就可以将两个 节点连在一起。
- 如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,再加入这条边一定就出现环了
- 如图所示,节点A 和节点 B 不在同一个集合,那么就可以将两个 节点连在一起。
-
题目要求返回最后出现的冗余边。当遍历到冗余边时,之前的边已经构建了连通性,此时检测到冗余的边即为最后一条导致环的边。
-
时间复杂度: O ( n ∗ α ( n ) ) O(n * \alpha (n)) O(n∗α(n))
2、代码
class Solution:def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:n = len(edges)p = list(range(n + 1))def find(x:int) -> int:if p[x] != x:p[x] = find(p[x])return p[x]def union(i,j):p[find(i)] = find(j)for a, b in edges:if find(a) != find(b):union(a, b)else:return [a,b]return []
二、力扣.冗余连接Ⅱ【hard】
题目链接:力扣冗余连接Ⅱ
视频链接:代码随想录
1、思路
- 冗余的边有两种情况:
- 入度为2的节点:节点有2个父节点
- 有向环
- 太复杂了,跳过
- 时间复杂度: O ( n ) O(n) O(n)
2、代码
class UnionFind:def __init__(self, n):self.ancestor = list(range(n))def union(self, index1: int, index2: int):self.ancestor[self.find(index1)] = self.find(index2)def find(self, index: int) -> int:if self.ancestor[index] != index:self.ancestor[index] = self.find(self.ancestor[index])return self.ancestor[index]class Solution:def findRedundantDirectedConnection(self, edges: List[List[int]]) -> List[int]:n = len(edges)uf = UnionFind(n + 1)parent = list(range(n + 1))conflict = -1cycle = -1for i, (node1, node2) in enumerate(edges):if parent[node2] != node2:conflict = ielse:parent[node2] = node1if uf.find(node1) == uf.find(node2):cycle = ielse:uf.union(node1, node2)if conflict < 0:return [edges[cycle][0], edges[cycle][1]]else:conflictEdge = edges[conflict]if cycle >= 0:return [parent[conflictEdge[1]], conflictEdge[1]]else:return [conflictEdge[0], conflictEdge[1]]
三、力扣
题目链接:力扣
left =x300
视频链接:代码随想录
题解链接:灵茶山艾府
1、思路
- 时间复杂度: O ( n ) O(n) O(n)
2、代码
四、力扣
题目链接:力扣
left =x300
视频链接:代码随想录
题解链接:灵茶山艾府
1、思路
- 时间复杂度: O ( n ) O(n) O(n)
2、代码