锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
瀹氫箟錛?br />
騫舵煡闆嗘眰MST+鏋氫婦杈癸紝鎬濊礬鍙傝?>https://leetcode.com/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/solutions/3929349/detailed-video-solution-java-c-python/
2 #Runtime: 2134 ms (Beats 50%)
3 #Memory: 13.4 MB (Beats 100%)
4
5 class UnionFind:
6 def __init__(self, n):
7 self.pa = list(range(n))
8
9
10 def find(self, x):
11 if self.pa[x] != x:
12 self.pa[x] = self.find(self.pa[x])
13 return self.pa[x]
14
15
16 def union(self, x, y):
17 px, py = self.find(x), self.find(y)
18 self.pa[px] = py
19
20
21 class Solution(object):
22 def findCriticalAndPseudoCriticalEdges(self, n, edges):
23 """
24 :type n: int
25 :type edges: List[List[int]]
26 :rtype: List[List[int]]
27 """
28 def find_MST(block, e):
29 uf = UnionFind(n)
30 wt = 0
31 if e != -1:
32 wt += edges[e][2]
33 uf.union(edges[e][0], edges[e][1])
34 for i in range(len(edges)):
35 if i == block:
36 continue
37 if uf.find(edges[i][0]) == uf.find(edges[i][1]):
38 continue
39 uf.union(edges[i][0], edges[i][1])
40 wt += edges[i][2]
41 for i in range(n):
42 if uf.find(i) != uf.find(0):
43 return float('inf')
44 return wt
45
46 c = []
47 pc = []
48 for i, e in enumerate(edges):
49 e.append(i)
50 edges.sort(key=lambda x: x[2])
51 mst = find_MST(-1, -1)
52 for i, e in enumerate(edges):
53 if mst < find_MST(i, -1):
54 c.append(e[3])
55 elif mst == find_MST(-1, i):
56 pc.append(e[3])
57 return [c, pc]
]]>
DFS
2 #Runtime: 154 ms (Beats 66.8%)
3 #Memory: 13.6 MB (Beats 94.53%)
4
5 class Solution(object):
6 def findCircleNum(self, isConnected):
7 """
8 :type isConnected: List[List[int]]
9 :rtype: int
10 """
11 ans = 0
12 n = len(isConnected)
13 vis = [0] * n
14
15 def DFS(node):
16 vis[node] = 1
17 for i in range(n):
18 if isConnected[node][i] == 1 and not vis[i]:
19 DFS(i)
20
21 for i in range(n):
22 if not vis[i]:
23 DFS(i)
24 ans += 1
25 return ans
BFS
2 #Runtime: 156 ms (Beats 61.49%)
3 #Memory: 13.8 MB (Beats 40.4%)
4
5 class Solution(object):
6 def findCircleNum(self, isConnected):
7 """
8 :type isConnected: List[List[int]]
9 :rtype: int
10 """
11 ans = 0
12 n = len(isConnected)
13 vis = [0] * n
14 for i in range(n):
15 if not vis[i]:
16 q = deque([i])
17 vis[i] = 1
18 ans += 1
19 while q:
20 x = q.popleft()
21 for j in range(n):
22 if not vis[j] and isConnected[x][j]:
23 vis[j] = 1
24 q.append(j)
25 return ans
騫舵煡闆?br />
2 #Runtime: 178 ms (Beats 21.88%)
3 #Memory: 13.5 MB (Beats 94.53%)
4
5 class Solution(object):
6 def findCircleNum(self, isConnected):
7 """
8 :type isConnected: List[List[int]]
9 :rtype: int
10 """
11 n = len(isConnected)
12 parent = [i for i in range(n)]
13
14 def find(x):
15 if parent[x] != x:
16 parent[x] = find(parent[x])
17 return parent[x]
18
19 def union(x, y):
20 fa, fb = find(x), find(y)
21 parent[fb] = fa
22
23 for i in range(n):
24 for j in range(n):
25 if isConnected[i][j]:
26 union(i, j)
27 return len(set([find(i) for i in range(n)]))
]]>
鎬濊礬涓錛氬緩鍥撅紝BFS
鎬濊礬浜岋細騫舵煡闆嗭紝鍐欐硶鍙傝冧簡Discussion
2 #Runtime: 25 ms (Beats 11.39%)
3 #Memory: 13.4 MB (Beats 73.42%)
4
5 class Solution(object):
6 def calcEquation(self, equations, values, queries):
7 """
8 :type equations: List[List[str]]
9 :type values: List[float]
10 :type queries: List[List[str]]
11 :rtype: List[float]
12 """
13 equ = {}
14
15 def find(x):
16 p, v = equ.setdefault(x, (x, 1))
17 if x != p:
18 r, w = find(p)
19 equ[x] = (r, w * v)
20 return equ[x]
21
22 def union(x, y, v):
23 px, pv = find(x)
24 py, pw = find(y)
25 if not v:
26 if px == py:
27 return pv / pw
28 else:
29 return -1
30 if px != py:
31 equ[px] = (py, pw / pv * v)
32
33 for (x, y), v in zip(equations, values):
34 union(x, y ,v)
35 ans = []
36 for x, y in queries:
37 if x in equ and y in equ:
38 ans.append(union(x, y, 0))
39 else:
40 ans.append(-1)
41 return ans
42
]]>
2 #Runtime: 160 ms (Beats 23.18%)
3 #Memory: 13.6 MB (Beats 95%)
4
5 class Solution(object):
6 def isBipartite(self, graph):
7 """
8 :type graph: List[List[int]]
9 :rtype: bool
10 """
11 parent = [i for i in range(len(graph))]
12
13 def find(x):
14 if parent[x] != x:
15 parent[x] = find(parent[x])
16 return parent[x]
17
18 def union(x, y):
19 fa, fb = find(x), find(y)
20 parent[fb] = fa
21
22 for i in range(len(graph)):
23 for j in range(len(graph[i])):
24 pi, pj = find(i), find(graph[i][j])
25 if pi == pj:
26 return False
27 union(graph[i][0], graph[i][j])
28
29 return True
]]>
2 #Runtime: 1874 ms (Beats 35.71%)
3 #Memory: 63.1 MB (Beats 71.43%)
4
5 class UnionFind:
6 def __init__(self, n):
7 self.parent = list(range(n + 1))
8 self.cc = n
9 def union(self, a, b):
10 fa = self.find(a)
11 fb = self.find(b)
12 if fa == fb:
13 return 0
14 self.parent[fa] = fb
15 self.cc -= 1
16 return 1
17
18 def find(self, a):
19 if self.parent[a] != a:
20 self.parent[a] = self.find(self.parent[a])
21 return self.parent[a]
22
23 def judge(self):
24 return self.cc == 1
25
26 class Solution(object):
27 def maxNumEdgesToRemove(self, n, edges):
28 """
29 :type n: int
30 :type edges: List[List[int]]
31 :rtype: int
32 """
33 alice, bob = UnionFind(n), UnionFind(n)
34
35 t = 0
36 for a, u, v in edges:
37 if a == 3:
38 t += alice.union(u, v) | bob.union(u, v)
39 if alice.judge() and bob.judge():
40 return len(edges) - t
41
42 for a, u, v in edges:
43 if a == 1:
44 t += alice.union(u, v)
45 elif a == 2:
46 t += bob.union(u, v)
47 if alice.judge() and bob.judge():
48 return len(edges) - t
49
50 if not alice.judge() or not bob.judge():
51 return -1
52
53 return len(edges) - t
]]>
2 #Runtime: 1668 ms (Beats 100%)
3 #Memory: 59.9 MB (Beats 100%)
4
5 class Solution(object):
6 def distanceLimitedPathsExist(self, n, edgeList, queries):
7 """
8 :type n: int
9 :type edgeList: List[List[int]]
10 :type queries: List[List[int]]
11 :rtype: List[bool]
12 """
13 parent = [i for i in range(n)]
14 rank = [i for i in range(n)]
15 def find(x, limit):
16 while x != parent[x]:
17 if dis[x] >= limit:
18 break
19 x = parent[x]
20 return x
21
22 def union(x, y, d):
23 fa = find(x, float('inf'))
24 fb = find(y, float('inf'))
25 if fa != fb:
26 if rank[fa] < rank[fb]:
27 parent[fa] = fb
28 dis[fa] = d
29 else:
30 parent[fb] = fa
31 dis[fb] = d
32 if rank[fa] == rank[fb]:
33 rank[fa] += 1
34
35 def judge(x, y, limit):
36 return find(x, limit) == find(y, limit)
37
38 dis = [0 for _ in range(n)]
39 edgeList.sort(key=lambda x: x[2])
40 for ed in edgeList:
41 union(ed[0], ed[1], ed[2])
42 ans = []
43 for q in queries:
44 ans.append(judge(q[0], q[1], q[2]))
45 return ans
]]>
2 #Runtime: 341 ms (Beats 65.91%)
3 #Memory: 13.9 MB (Beats 79.55%)
4
5 class Solution(object):
6 def numSimilarGroups(self, strs):
7 """
8 :type strs: List[str]
9 :rtype: int
10 """
11 fa = [i for i in range(len(strs))]
12 #rank = [0] * len(strs)
13 def find(x):
14 i = x
15 while x != fa[x]:
16 x = fa[x]
17 fa[i] = x
18 return x
19
20 def union(a, b):
21 fa[find(a)] = find(b)
22
23 def is_similar(x, y):
24 tp = 0
25 for i in range(len(x)):
26 if x[i] != y[i]:
27 tp += 1
28 if tp > 2:
29 return False
30 return True
31
32 n_group = len(strs)
33 for i in range(len(strs)):
34 for j in range(i + 1, len(strs)):
35 if find(i) != find(j) and is_similar(strs[i], strs[j]):
36 n_group -= 1
37 union(i, j)
38 return n_group
]]>
2 #Runtime: 2121 ms (Beats 54.5%)
3 #Memory: 114.9 MB (Beats 16.22%)
4
5 class Solution(object):
6 def countPairs(self, n, edges):
7 """
8 :type n: int
9 :type edges: List[List[int]]
10 :rtype: int
11 """
12 edge = defaultdict(list)
13 for x, y in edges:
14 edge[x].append(y)
15 edge[y].append(x)
16 vis = [0] * n
17
18 def DFS(node):
19 vis[node] = 1
20 self.tp += 1
21 for y in edge[node]:
22 if not vis[y]:
23 DFS(y)
24
25 ncc = []
26 ans = 0
27 for i in range(n):
28 if not vis[i]:
29 self.tp = 0
30 DFS(i)
31 ncc.append(self.tp)
32 total = 0
33 for j in range(len(ncc)):
34 ans += (n - total - ncc[j]) * ncc[j]
35 total += ncc[j]
36 return ans
]]>
2 #Runtime: 2295 ms (Beats 93.75%)
3 #Memory: 39 MB (Beats 81.25%)
4
5 class UnionFind:
6 def __init__(self, n):
7 self.parent = [i for i in range(n + 1)]
8 def find(self, x):
9 i = x
10 while x != self.parent[x]:
11 x = self.parent[x]
12 self.parent[i] = x
13 return x
14 def union(self, x, y):
15 self.parent[self.find(x)] = self.find(y)
16
17 class Solution(object):
18 def numberOfGoodPaths(self, vals, edges):
19 """
20 :type vals: List[int]
21 :type edges: List[List[int]]
22 :rtype: int
23 """
24 uf = UnionFind(len(vals))
25 node_val_set = defaultdict(set)
26 node_dict = defaultdict(list)
27 ans = len(vals)
28 for x, y in edges:
29 node_val_set[vals[x]].add(x)
30 node_val_set[vals[y]].add(y)
31 node_dict[x].append(y)
32 node_dict[y].append(x)
33 for i in sorted(node_val_set.keys()):
34 for j in node_val_set[i]:
35 for k in node_dict[j]:
36 if vals[k] <= i:
37 uf.union(j, k)
38 cnt = defaultdict(int)
39 for j in node_val_set[i]:
40 cnt[uf.find(j)] += 1
41 for r in cnt.keys():
42 ans += (cnt[r] - 1) * cnt[r] // 2
43 return ans
]]>
鍙︾粰鍑轟竴涓猙aseStr錛岃緭鍑轟笌涔嬪絳夌殑瀛楃鎺掑簭鏈灝忕殑瀛楃涓?br />騫舵煡闆嗭紝灝唖1鍜宻2瀵瑰簲浣嶇疆鐨勫瓧絎︿竴涓騫跺叆鐩稿悓闆嗗悎錛屾敞鎰忓湪鍚堝茍鏃舵案榪滈夋嫨杈冨皬鐨勫瓧絎︿綔涓虹埗鑺傜偣
2 #Runtime: 26 ms (Beats 87.50%)
3 #Memory: 13.5 MB (Beats 81.25%)
4
5 class UnionFind:
6 def __init__(self):
7 self.parent = {}
8 def find(self, x):
9 if x not in self.parent:
10 self.parent[x] = x
11 i = x
12 while x != self.parent[x]:
13 x = self.parent[x]
14 self.parent[i] = x
15 return x
16 def union(self, x, y):
17 rx = self.find(x)
18 ry = self.find(y)
19 if rx > ry:
20 self.parent[rx] = ry
21 else:
22 self.parent[ry] = rx
23
24 class Solution(object):
25 def smallestEquivalentString(self, s1, s2, baseStr):
26 """
27 :type s1: str
28 :type s2: str
29 :type baseStr: str
30 :rtype: str
31 """
32 uf = UnionFind()
33 for i in range(len(s1)):
34 uf.union(s1[i], s2[i])
35 ans = []
36 for c in baseStr:
37 ans.append(uf.find(c))
38 return ''.join(ans)
]]>
2 #Runtime: 2223 ms (Beats 5.11%)
3 #Memory: 19.1 MB (Beats 72.26%)
4
5 class UnionFind:
6 def __init__(self, n):
7 self.parent = [i for i in range(n + 1)]
8 def find(self, x):
9 i = x
10 while self.parent[x] != x:
11 x = self.parent[x]
12 self.parent[i] = x
13 return x
14 def union(self, x, y):
15 self.parent[self.find(x)] = self.find(y)
16
17
18 class Solution(object):
19 def possibleBipartition(self, n, dislikes):
20 """
21 :type n: int
22 :type dislikes: List[List[int]]
23 :rtype: bool
24 """
25 if n == 1:
26 return True
27 graph_dict = {}
28 for d in dislikes:
29 if d[0] not in graph_dict:
30 graph_dict[d[0]] = [d[1]]
31 else:
32 graph_dict[d[0]].append(d[1])
33 if d[1] not in graph_dict:
34 graph_dict[d[1]] = [d[0]]
35 else:
36 graph_dict[d[1]].append(d[0])
37 uf_set = UnionFind(n)
38 for x in graph_dict.keys():
39 for i in range(len(graph_dict[x]) - 1):
40 uf_set.union(graph_dict[x][i], graph_dict[x][i + 1])
41 if uf_set.find(x) == uf_set.find(graph_dict[x][0]):
42 return False
43 return True
]]>
絎﹀悎鍚岃or鍚屽垪鐨勭煶瀛愰泦鍚堢粍鎴愪竴涓繛閫氬垎閲忥紝姣忎釜榪為氬垎閲忓彲浠ュ彧鐣欎笅涓棰楃煶瀛愶紙娌跨潃DFS璺緞涓璺幓鎺夌煶瀛愶級
鏂規硶涓錛欴FS姹傝繛閫氬垎閲忎釜鏁?br />
2 #Runtime: 1060 ms
3 #Memory Usage: 14.5 MB
4
5 class Solution(object):
6 def DFS(self, r, c):
7 if len(self.dict_stones_row[r]) > 1:
8 for j in self.dict_stones_row[r]:
9 if [r, j] not in self.vis:
10 self.vis.append([r, j])
11 self.DFS(r, j)
12 if len(self.dict_stones_col[c]) > 1:
13 for j in self.dict_stones_col[c]:
14 if [j, c] not in self.vis:
15 self.vis.append([j, c])
16 self.DFS(j, c)
17 return
18
19 def removeStones(self, stones):
20 """
21 :type stones: List[List[int]]
22 :rtype: int
23 """
24 self.dict_stones_row = {}
25 self.dict_stones_col = {}
26 self.vis = []
27 for i in stones:
28 if i[0] not in self.dict_stones_row:
29 self.dict_stones_row[i[0]] = []
30 self.dict_stones_row[i[0]].append(i[1])
31 if i[1] not in self.dict_stones_col:
32 self.dict_stones_col[i[1]] = []
33 self.dict_stones_col[i[1]].append(i[0])
34 nc = 0
35 for i in stones:
36 if i not in self.vis:
37 self.DFS(i[0], i[1])
38 nc += 1
39 return len(stones) - nc
鏂規硶浜岋細騫舵煡闆嗭紝鏄疍FS鐨勫嚑涔?鍊嶉熷害錛岀湅Discussion鑾峰緱鐨勬濊礬錛屽皬鎶宸ф槸鍙互灝嗙旱鍧愭爣i鐢▇i鎿嶄綔杞寲涓哄拰妯潗鏍囨棤overlap鐨勫鹼紝榪欐牱鍙互濉炶繘涓涓茍鏌ラ泦緇熶竴澶勭悊榪欎釜騫舵煡闆嗗啓娉曚篃寰堢畝媧?br />
2 #Runtime: 129 ms
3 #Memory Usage: 14.1 MB
4
5 class Solution(object):
6 def find(self, x):
7 if x != self.uf.setdefault(x, x):
8 self.uf[x] = self.find(self.uf[x])
9 return self.uf[x]
10
11 def removeStones(self, stones):
12 """
13 :type stones: List[List[int]]
14 :rtype: int
15 """
16 self.uf = {}
17 for i, j in stones:
18 self.uf[self.find(i)] = self.find(~j)
19 return len(stones) - len({self.find(x) for x in self.uf})
]]>