Skip to content

Detect Squares

LeetCode Problem

# https://leetcode.com/problems/detect-squares/
"""
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.

Trick for detecting squares/rectangle in a grid
Count of occurrences matter : more count/duplicates : more squares. (hashmap)
Trick:
    Find diagonal point. How to verify if points are square by diagonal?
        height difference = width difference :: Diagonal : Form a square
    qx,qy and x,y :: if x, qy and qx, y are in hashmap : square can be formed and if multiple counts : multiple count by squares
"""

# defaultdict : if key not present : 0 (Default Value)
# list can't be a key for hashmap in python : convert to tuple.
# use list not hashmap to store points (we need duplicates)
from collections import defaultdict


class DetectSquares:
    def __init__(self):
        self.ptsCounter = defaultdict(int)
        self.pts = []

    def add(self, point):
        self.ptsCounter[tuple(point)] += 1
        self.pts.append(point)

    def count(self, point):
        # if diagonals same : we can form square
        # area should be positive : 2 points can't be stacked on top of each other : no square
        ans = 0
        px, py = point
        for x, y in self.pts:
            if (abs(py - y) != abs(px - x)) or x == px or y == py:
                continue  # can't form square
            ans += self.ptsCounter[(x, py)] * self.ptsCounter[(px, y)]
        return ans


if __name__ == "__main__":
    obj = DetectSquares()
    obj.add([3, 10])
    obj.add([11, 2])
    obj.add([3, 2])
    obj.count([11, 10])  # 1
    obj.count([14, 8])  # 0
    obj.add([11, 2])
    obj.count([11, 10])  # 2