-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path2013_Detect_Squares.py
More file actions
73 lines (53 loc) · 2.68 KB
/
2013_Detect_Squares.py
File metadata and controls
73 lines (53 loc) · 2.68 KB
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
63
64
65
66
67
68
69
70
71
72
73
'''
Problem URL: https://leetcode.com/problems/detect-squares/
### Problem Description
You are given a stream of points on the X-Y plane. Design an algorithm that:
- Adds new points from the stream into a data structure. Duplicate points are allowed
and should be treated as different points.
- Given a query point, counts the number of ways to choose three points from the data
structure such that the three points and the query point form an axis-aligned square
with positive area.
An **axis-aligned square** is a square whose edges are all the same length and are either
parallel or perpendicular to the x-axis and y-axis.
Implement the `DetectSquares` class:
- `DetectSquares()` Initializes the object with an empty data structure.
- `void add(int[] point)` Adds a new point `point = [x, y]` to the data structure.
- `int count(int[] point)` Counts the number of ways to form axis-aligned squares with
point `point = [x, y]` as described above.
### End Description
# Approach
## Adding Points
Since duplicate points can be used to form multiple distinct, countable squares, we will
convert the point from a list to a tuple so we can track the number of times it has been
added in a dictionary.
*Note: `defaultdict(int)` defaults to 0 for new values*
## Counting Squares
To reduce the amount of iterating, we loop through the items of `self.points` searching
for points that can serve as the opposite corner of a square. For each such point found,
we check if `self.points` contains the other two necessary corners. If so, we calculate
how many identical squares can be created by multiplying the instances of each of the
three points in `self.points`. We add this number to the running count, which we return
once the for loop is completed.
Execution time: 378 ms (faster than 90.28%)
Memory usage: 15.9 MB (smaller than 63.45%)
Time complexity: O(n)
Space complexity: O(n)
My solution on leetcode: https://leetcode.com/problems/detect-squares/solutions/2764859/python3-simple-fast-elegant-beats-90/
'''
from collections import defaultdict
class DetectSquares:
def __init__(self):
self.points = defaultdict(int)
def add(self, point: List[int]) -> None:
self.points[tuple(point)] += 1
def count(self, point: List[int]) -> int:
square_count = 0
x1, y1 = point
for (x2, y2), n in self.points.items():
x_dist, y_dist = abs(x1 - x2), abs(y1 - y2)
if x_dist == y_dist and x_dist > 0:
corner1 = (x1, y2)
corner2 = (x2, y1)
if corner1 in self.points and corner2 in self.points:
square_count += n * self.points[corner1] * self.points[corner2]
return square_count