Amazon sells books, every book has books which are strongly associated with it. Given ListA and ListB,indicates that ListA [i] is associated with ListB [i] which represents the book and associated books. Output the largest set associated with each other(output in any sort). You can assume that there is only one of the largest set.
Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements are emails representing emails of the account. Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Return the email in sorted order
An emailToID map
An emailToName map
An ans map
Use EmailToName to update the answer
classUF:def__init__(self): self.p = [i for i inrange(10000)]deffind(self,x):if x != self.p[x]: self.p[x]= self.find(self.p[x])return self.p[x]defunion(self,x1,x2): self.p[self.find(x1)]= self.find(x2)classSolution:defaccountsMerge(self,accounts: List[List[str]]) -> List[List[str]]: uf =UF() email_to_id ={} email_to_name ={} i =0for acc in accounts: name = acc[0]for email in acc[1:]: email_to_name[email]= nameif email notin email_to_id: email_to_id[email]= i i+=1 uf.union(email_to_id[acc[1]], email_to_id[email]) ans = collections.defaultdict(list)for email,idin email_to_id.items(): ans[uf.find(id)].append(email)return [[email_to_name[li[0]]] +sorted(li)for li in ans.values()]
684. Redundant Connection
Undirect graph, use union- find
classUF:def__init__(self): self.p = [i for i inrange(1001)]deffind(self,x):if x != self.p[x]: self.p[x]= self.find(self.p[x])return self.p[x]defunion(self,x1,x2): self.p[self.find(x1)]= self.find(x2)classSolution:deffindRedundantConnection(self,edges: List[List[int]]) -> List[int]: uf =UF() ans =Nonefor e in edges:if uf.find(e[0])== uf.find(e[1]): ans = e uf.union(e[0], e[1])return ans
685. Redundant Connection II
Direct Graph
"""根據parent做出判斷 1. p_a != p_b if p_b != e[1]: node的parent不是自己,已經有其他parent -> multiple parents 不做union, 先保留答案 else: union a and b 2. p_a == p_b: cycle 如果兩個條件都符合,代表第一個parent先出現了,並且造成cycle所以有兩個candidate 找到e[1]的第一個parent Example:[[2,1],[3,1],[4,2],[1,4]]"""classUF:def__init__(self): self.p = [i for i inrange(1001)]deffind(self,x):if x != self.p[x]: self.p[x]= self.find(self.p[x])return self.p[x]# 注意有方向關係,x2的parent要指向x1defunion(self,x1,x2): self.p[self.find(x2)]= self.find(x1)classSolution:deffindRedundantDirectedConnection(self,edges: List[List[int]]) -> List[int]: uf =UF() cand1 =None cand2 =Nonefor e in edges:if uf.find(e[0])!= uf.find(e[1]):if uf.find(e[1])!= e[1]: cand1 = eelse: uf.union(e[0], e[1])else: cand2 = e ifnot cand2:return cand1ifnot cand1:return cand2for e in edges:if e[1]== cand1[1]:return e return []
1202. Smallest String With Swap
Input: s ="dcab", pairs = [[0,3],[1,2],[0,2]]Output:"abcd"Explaination:Swap s[0]and s[3], s ="bcad"Swap s[0]and s[2], s ="acbd"Swap s[1]and s[2], s ="abcd"
"""[0, 1], [1, 2] -> [0, 1, 2] 代表這中間的c皆可互換sort the character array, 並依序把ch指派到idx上"""classUF:def__init__(self,n): self.p =list(range(n))deffind(self,x):if x != self.p[x]: self.p[x]= self.find(self.p[x])return self.p[x]defunion(self,x,y): self.p[self.find(x)]= self.find(y)classSolution:defsmallestStringWithSwaps(self,s:str,pairs: List[List[int]]) ->str: n =len(s) uf =UF(n) group =defaultdict(list)# union indexfor p in pairs: uf.union(p[0], p[1])# record the characters in the same groupfor idx inrange(n): group[uf.find(idx)].append(s[idx])# sort the charactersfor v in group.values(): v.sort() build = []# put the character but sequencefor idx inrange(n): build.append(group[uf.find(idx)].pop(0))return''.join(build)
924. Minimize Malware Spread
In a network of nodes, each node i is directly connected to another node j if and only if graph[i][j] = 1. Some nodes initial are initially infected by malware. We will remove one node from the initial list. Return the node that if removed, would minimize the affected nodes
Need to know size of the each init group
If there are 2 inits in group, then it will eventually effected no matter remove any of the node
Update when 1. group size is bigger 2. Same size but with smaller index
classDSU:def__init__(self,n): self.p = [i for i inrange(n)] self.size = [1] * ndeffind(self,x):if x != self.p[x]: self.p[x]= self.find(self.p[x])return self.p[x]defunion(self,x,y): xp, yp = self.find(x), self.find(y)if xp == yp:return self.p[xp]= yp self.size[yp]+= self.size[xp]defgetSize(self,x):return self.size[self.find(x)]classSolution:defminMalwareSpread(self,graph: List[List[int]],initial: List[int]) ->int: n =len(graph) dsu =DSU(n)# union connected nodesfor i inrange(n):for j inrange(i):if graph[i][j] ==1: dsu.union(i, j)# check if init in same set uniqueCount = collections.defaultdict(int)for init in initial: uniqueCount[dsu.find(init)]+=1 ans =-1for init in initial:if uniqueCount[dsu.find(init)]==1:# the union only has 1 initif ans ==-1: ans = initelif dsu.getSize(init)> dsu.getSize(ans): ans = initelif dsu.getSize(init)== dsu.getSize(ans)and init < ans: ans = initreturn ans if ans !=-1elsemin(initial)