forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherect-the-fence-ii.py
62 lines (52 loc) · 1.98 KB
/
erect-the-fence-ii.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Time: O(n) on average
# Space: O(n)
import random
# reference: https://en.wikipedia.org/wiki/Smallest-circle_problem
class Solution(object):
def outerTrees(self, trees):
"""
:type trees: List[List[int]]
:rtype: List[float]
"""
def dist(a, b):
return ((a[0]-b[0])**2 + (a[1]-b[1])**2)**0.5
def inside(c, p):
return dist(c[0], p) < c[1]+EPS
def circle_center(bx, by, cx, cy):
B = bx*bx + by*by
C = cx*cx + cy*cy
D = bx*cy - by*cx
return [float(cy*B - by*C)/(2*D),
float(bx*C - cx*B)/(2*D)]
def circle_from_2_points(A, B):
C = [(A[0]+B[0])/2.0, (A[1]+B[1])/2.0]
return [C, dist(A, B)/2.0]
def circle_from_3_points(A, B, C):
I = circle_center(B[0]-A[0], B[1]-A[1],
C[0]-A[0], C[1]-A[1])
I[0] += A[0]
I[1] += A[1]
return [I, dist(I, A)]
def trivial(boundaries): # circumscribed circle
if not boundaries:
return None
if len(boundaries) == 1:
return [boundaries[0], 0.0]
if len(boundaries) == 2:
return circle_from_2_points(boundaries[0], boundaries[1])
return circle_from_3_points(boundaries[0], boundaries[1], boundaries[2])
def Welzl(points, boundaries, curr):
if curr == len(points) or len(boundaries) == 3:
return trivial(boundaries)
result = Welzl(points, boundaries, curr+1)
if result is not None and inside(result, points[curr]):
return result
boundaries.append(points[curr])
result = Welzl(points, boundaries, curr+1)
boundaries.pop()
return result
EPS = 1e-5
random.seed(0)
random.shuffle(trees)
result = Welzl(trees, [], 0)
return result[0][0], result[0][1], result[1]