PracticeNeetCode ↗LeetCode ↗
Design a data structure that supports adding points, and — given a query point — counting how many axis-aligned squares can be formed using that query point plus three previously added points.
count mapping (x, y) → number of times added.add(x, y): increment count[(x, y)].count_squares(px, py): for every stored point (x, y) with x == px and y != py, treat it as the vertical-edge partner, with side = y - py.nx = px + side and nx = px - side, multiply the counts of (x, y), (nx, py), and (nx, y) together and add to the running total.Time: O(n) per query, where n is the number of distinct added points — Space: O(n)
from collections import defaultdict
class DetectSquares:
def __init__(self):
self.count = defaultdict(int)
def add(self, point: list[int]) -> None:
self.count[tuple(point)] += 1
def count_squares(self, point: list[int]) -> int:
px, py = point
total = 0
for (x, y), c in list(self.count.items()):
if x != px or y == py:
continue
side = y - py
for nx in (px + side, px - side):
total += c * self.count[(nx, py)] * self.count[(nx, y)]
return totalHow the solution above works, piece by piece.
count maps each point to how many times it was added (duplicates count separately).count_squares tries every stored point directly above or below the query (same x, different y). That fixes the side length side = y − py.nx = px ± side, the other corners are (nx, py) and (nx, y).count(vertical partner) × count(nx, py) × count(nx, y); a missing corner contributes 0.add is O(1); a query is O(number of distinct stored points).Running it on points (3, 10), (11, 2), (3, 2) and query (11, 10):