Use this to learn the idea, then write your own version.
123 45class Solution(object):6 def maxPartitionFactor(self, points):7 """8 :type points: List[List[int]]9 :rtype: int10 """11 class UnionFind(object): 12 def __init__(self, n):13 self.set = range(n)14 self.rank = [0]*n15 self.parity = [0]*n 16 17 def find_set(self, x):18 stk = []19 while self.set[x] != x: 20 stk.append(x)21 x = self.set[x]22 while stk:23 y = stk.pop()24 self.parity[y] ^= self.parity[self.set[y]] 25 self.set[y] = x26 return x27 28 def union_set(self, x, y):29 ox, oy = x, y 30 x, y = self.find_set(x), self.find_set(y)31 if x == y:32 return self.parity[ox] != self.parity[oy] 33 if self.rank[x] > self.rank[y]: 34 x, y = y, x35 ox, oy = oy, ox 36 if self.rank[x] == self.rank[y]:37 self.rank[y] += 138 self.set[x] = self.set[y]39 self.parity[x] = self.parity[ox]^self.parity[oy]^1 40 return True41 42 def dist(u, v):43 return abs(points[u][0]-points[v][0])+abs(points[u][1]-points[v][1])44 45 sorted_dists = sorted((dist(u, v), u, v) for u in xrange(len(points)) for v in xrange(u+1, len(points)))46 uf = UnionFind(len(points))47 return next((d for d, u, v in sorted_dists if not uf.union_set(u, v)), 0)48 49 50515253class Solution2(object):54 def maxPartitionFactor(self, points):55 """56 :type points: List[List[int]]57 :rtype: int58 """59 class UnionFind(object): 60 def __init__(self, n):61 self.set = range(n)62 self.rank = [0]*n63 64 def find_set(self, x):65 stk = []66 while self.set[x] != x: 67 stk.append(x)68 x = self.set[x]69 while stk:70 y = stk.pop()71 self.set[y] = x72 return x73 74 def union_set(self, x, y):75 x, y = self.find_set(x), self.find_set(y)76 if x == y:77 return False78 if self.rank[x] > self.rank[y]: 79 x, y = y, x80 if self.rank[x] == self.rank[y]:81 self.rank[y] += 182 self.set[x] = self.set[y]83 return True84 85 def dist(u, v):86 return abs(points[u][0]-points[v][0])+abs(points[u][1]-points[v][1])87 88 sorted_dists = sorted((dist(u, v), u, v) for u in xrange(len(points)) for v in xrange(u+1, len(points)))89 uf = UnionFind(len(points))90 lookup = [-1]*len(points)91 for d, u, v in sorted_dists:92 if uf.find_set(u) == uf.find_set(v):93 return d94 if lookup[u] != -1:95 uf.union_set(lookup[u], v)96 else:97 lookup[u] = v98 if lookup[v] != -1:99 uf.union_set(lookup[v], u)100 else:101 lookup[v] = u102 return 0103 104 105106107108class Solution3(object):109 def maxPartitionFactor(self, points):110 """111 :type points: List[List[int]]112 :rtype: int113 """114 INF = float("inf")115 def binary_search_right(left, right, check):116 while left <= right:117 mid = left+(right-left)2118 if not check(mid):119 right = mid-1120 else:121 left = mid+1122 return right123 124 def dist(u, v):125 return abs(points[u][0]-points[v][0])+abs(points[u][1]-points[v][1])126 127 def is_bipartite(d):128 def bfs(u):129 if lookup[u] != -1:130 return True131 lookup[u] = 0132 q = [u]133 while q:134 new_q = []135 for u in q:136 for v in xrange(len(points)):137 if not (v != u and dist(v, u) < d):138 continue139 if lookup[v] != -1:140 if lookup[v] != lookup[u]^1:141 return False142 continue143 lookup[v] = lookup[u]^1144 new_q.append(v)145 q = new_q146 return True 147 148 lookup = [-1]*len(points)149 return all(bfs(u) for u in xrange(len(points)))150 151 sorted_dists = sorted({dist(u, v) for u in xrange(len(points)) for v in xrange(u+1, len(points))}|{INF})152 left, right = 0, len(sorted_dists)-1153 result = binary_search_right(left, right, lambda i: is_bipartite(sorted_dists[i]))154 return sorted_dists[result] if sorted_dists[result] != INF else 0155 156 157158159160class Solution4(object):161 def maxPartitionFactor(self, points):162 """163 :type points: List[List[int]]164 :rtype: int165 """166 def binary_search_right(left, right, check):167 while left <= right:168 mid = left+(right-left)2169 if not check(mid):170 right = mid-1171 else:172 left = mid+1173 return right174 175 def dist(u, v):176 return abs(points[u][0]-points[v][0])+abs(points[u][1]-points[v][1])177 178 def is_bipartite(d):179 def bfs(u):180 if lookup[u] != -1:181 return True182 lookup[u] = 0183 q = [u]184 while q:185 new_q = []186 for u in q:187 for v in xrange(len(points)):188 if not (v != u and dist(v, u) < d):189 continue190 if lookup[v] != -1:191 if lookup[v] != lookup[u]^1:192 return False193 continue194 lookup[v] = lookup[u]^1195 new_q.append(v)196 q = new_q197 return True 198 199 lookup = [-1]*len(points)200 return all(bfs(u) for u in xrange(len(points)))201 202 mx = max(dist(u, v) for u in xrange(len(points)) for v in xrange(u+1, len(points)))203 left, right = 0, mx+1204 result = binary_search_right(left, right, is_bipartite)205 return result if result != mx+1 else 0206