Detect Squares - Problem

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.

Input & Output

Example 1 — Basic Square Formation
$ Input: operations = ["DetectSquares", "add", "add", "add", "count", "count", "add", "count"], points = [[], [3,10], [11,2], [3,2], [11,10], [14,8], [11,2], [11,10]]
Output: [null, null, null, null, 1, 0, null, 1]
💡 Note: DetectSquares detectSquares = new DetectSquares(); detectSquares.add([3, 10]); detectSquares.add([11, 2]); detectSquares.add([3, 2]); detectSquares.count([11, 10]); // return 1. You can choose: [3, 10], [11, 2], [3, 2] detectSquares.count([14, 8]); // return 0. No valid square. detectSquares.add([11, 2]); // duplicate point detectSquares.count([11, 10]); // return 1 (still same square)
Example 2 — No Valid Squares
$ Input: operations = ["DetectSquares", "add", "add", "count"], points = [[], [0, 0], [1, 2], [0, 0]]
Output: [null, null, null, 0]
💡 Note: Points (0,0), (1,2), and query (0,0) cannot form any square with positive area, so count returns 0.
Example 3 — Multiple Squares with Duplicates
$ Input: operations = ["DetectSquares", "add", "add", "add", "add", "count"], points = [[], [0, 0], [0, 1], [1, 0], [0, 0], [1, 1]]
Output: [null, null, null, null, null, 2]
💡 Note: Query point (1,1) can form a square with points (0,0), (0,1), (1,0). Since (0,0) appears twice, there are 2 ways to form this square.

Constraints

  • At most 3000 calls in total will be made to add and count.
  • 0 <= point[0], point[1] <= 1000

Visualization

Tap to expand
Detect Squares - Hash Map Approach INPUT X Y (3,10) (11,2)x2 (3,2) Query(11,10) Hash Map Structure: x_coord --> {y: count} 3: {10:1, 2:1} 11: {2:2} Stores points by x-coord with y counts ALGORITHM STEPS 1 Store Points Map x->{y:count} 2 For Query (qx,qy) Find diagonal points 3 Check Diagonal (px,py) |px-qx| == |py-qy| 4 Count Squares Multiply corner counts Example: count(11,10) (3,10) Q(11,10) (3,2) (11,2) count = 1*1*1 = 1 FINAL RESULT Operations Trace: DetectSquares() --> null add([3,10]) --> null add([11,2]) --> null add([3,2]) --> null count([11,10]) --> 1 count([14,8]) --> 0 add([11,2]) --> null count([11,10]) --> 2 Output Array: [null,null,null,null,1,0,null,2] OK - Squares Counted! Key Insight: For axis-aligned squares, given query point Q and diagonal point P, the side length equals |Qx-Px| = |Qy-Py|. The other two corners are (Qx,Py) and (Px,Qy). Multiply their counts for total squares. Time: O(n) per query. TutorialsPoint - Detect Squares | Hash Map with Coordinate Counting Approach
Asked in
Google 23 Amazon 18 Microsoft 15 Apple 12
23.4K Views
Medium Frequency
~25 min Avg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen