Maximum Squares possible parallel to both axes from N distinct points
Given Xi and Yi co-ordinate of N distinct points in the 2-D Plane, the task is to count the number of squares that can be formed from these points that are parallel to both X and Y-axis.
Examples:
Input : X[] = { 0, 2, 0, 2 }, Y[] = { 0, 2, 2, 0 }
Output : 1
Explanation: Only one Square can be formed using these points –
(0, 2)(2, 2)
(0, 0)(2, 0)
Input : X[] = { 3, 2, 0, 6 }, Y[] = { 0, 2, 0, 6 }
Output : 0
Explanation: No Square can be formed using these points –
(3,0),(2,0), (0,0), (6,6)
Naive Approach: Iterate over all possible combinations of four points and check if a square can be formed that is parallel to both X and Y-axis. The time complexity of this approach would be O(N4).
Efficient Approach: We can observe that for any four points to make a required square, the following conditions must hold true –
- The points lying in the same horizontal line must have the same Y co-ordinates.
- The points lying in the same vertical line must have the same X co-ordinates.
- The distance between these points should be same.
Thus the four points of any square can be written as P1(X1, Y1), P2(X2, Y1), P3(X2, Y2) and P4(X1, Y2) in clockwise direction.
Consider any two points on the same horizontal or vertical line from the given ones. Calculate the distance between them. Based on that, form the other two points. Now check if both of the given points are present or not. If so, it ensures that a square is present. Hence, increase the count and proceed further.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countSquares( int * X, int * Y, int N)
{
int count = 0;
set<pair< int , int > > points;
map< int , vector< int > > vertical;
for ( int i = 0; i < N; i++) {
points.insert({ X[i], Y[i] });
}
for ( int i = 0; i < N; i++) {
vertical[X[i]].push_back(Y[i]);
}
for ( auto line : vertical) {
int X1 = line.first;
vector< int > yList = line.second;
for ( int i = 0; i < yList.size(); i++) {
int Y1 = yList[i];
for ( int j = i + 1; j < yList.size(); j++) {
int Y2 = yList[j];
int side = abs (Y1 - Y2);
int X2 = X1 + side;
if (points.find({ X2, Y1 }) != points.end()
and points.find({ X2, Y2 }) != points.end())
count++;
}
}
}
return count;
}
int main()
{
int X[] = { 0, 2, 0, 2 }, Y[] = { 0, 2, 2, 0 };
int N = sizeof (X) / sizeof (X[0]);
cout << countSquares(X, Y, N);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static int countSquares( int [] X, int [] Y, int N)
{
int count = 0 ;
HashSet<String> points = new HashSet<String>();
HashMap<Integer, ArrayList<Integer> > vertical = new HashMap<Integer, ArrayList<Integer>>();
for ( int i = 0 ; i < N; i++) {
points.add( String.valueOf(X[i]) + "#" + String.valueOf(Y[i]));
}
for ( int i = 0 ; i < N; i++) {
if (!vertical.containsKey(X[i]))
vertical.put(X[i], new ArrayList<Integer>());
ArrayList<Integer> l1 = vertical.get(X[i]);
l1.add(Y[i]);
vertical.put(X[i], l1);
}
for (var line : vertical.entrySet()) {
int X1 = line.getKey();
ArrayList<Integer> yList = line.getValue();
for ( int i = 0 ; i < yList.size(); i++) {
int Y1 = yList.get(i);
for ( int j = i + 1 ; j < yList.size(); j++) {
int Y2 = yList.get(j);
int side = Math.abs(Y1 - Y2);
int X2 = X1 + side;
if (points.contains( String.valueOf(X2) + "#" + String.valueOf(Y1)) && points.contains( String.valueOf(X2) + "#" + String.valueOf(Y2)))
count++;
}
}
}
return count;
}
public static void main(String[] args)
{
int [] X = { 0 , 2 , 0 , 2 };
int [] Y = { 0 , 2 , 2 , 0 };
int N = X.length;
System.out.println(countSquares(X, Y, N));
}
}
|
Python3
def countSquares(X, Y, N) :
count = 0 ;
points = [];
vertical = dict .fromkeys(X, None );
for i in range (N) :
points.append((X[i], Y[i]));
for i in range (N) :
if vertical[X[i]] is None :
vertical[X[i]] = [Y[i]];
else :
vertical[X[i]].append(Y[i]);
for line in vertical :
X1 = line;
yList = vertical[line];
for i in range ( len (yList)) :
Y1 = yList[i];
for j in range (i + 1 , len (yList)) :
Y2 = yList[j];
side = abs (Y1 - Y2);
X2 = X1 + side;
if ( X2, Y1 ) in points and ( X2, Y2 ) in points :
count + = 1 ;
return count;
if __name__ = = "__main__" :
X = [ 0 , 2 , 0 , 2 ]; Y = [ 0 , 2 , 2 , 0 ];
N = len (X);
print (countSquares(X, Y, N));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int countSquares( int [] X, int [] Y, int N)
{
int count = 0;
HashSet< string > points = new HashSet< string >();
Dictionary< int , List< int > > vertical = new Dictionary< int , List< int >>();
for ( int i = 0; i < N; i++) {
points.Add( Convert.ToString(X[i]) + "#" + Convert.ToString(Y[i]));
}
for ( int i = 0; i < N; i++) {
if (!vertical.ContainsKey(X[i]))
vertical[X[i]] = new List< int >();
vertical[X[i]].Add(Y[i]);
}
foreach ( var line in vertical) {
int X1 = line.Key;
List< int > yList = line.Value;
for ( int i = 0; i < yList.Count; i++) {
int Y1 = yList[i];
for ( int j = i + 1; j < yList.Count; j++) {
int Y2 = yList[j];
int side = Math.Abs(Y1 - Y2);
int X2 = X1 + side;
if (points.Contains( Convert.ToString(X2) + "#" + Convert.ToString(Y1)) && points.Contains( Convert.ToString(X2) + "#" + Convert.ToString(Y2)))
count++;
}
}
}
return count;
}
public static void Main( string [] args)
{
int [] X = { 0, 2, 0, 2 };
int [] Y = { 0, 2, 2, 0 };
int N = X.Length;
Console.WriteLine(countSquares(X, Y, N));
}
}
|
Javascript
function countSquares(X, Y, N)
{
let count = 0;
let points = new Set();
let vertical = {};
for ( var i = 0; i < N; i++) {
points.add(X[i] + "#" + Y[i]);
}
for ( var i = 0; i < N; i++) {
if (!vertical.hasOwnProperty(X[i]))
vertical[X[i]] = [];
vertical[X[i]].push(Y[i]);
}
for ( var [X1, yList] of Object.entries(vertical)) {
X1 = parseInt(X1)
for ( var i = 0; i < yList.length; i++) {
let Y1 = yList[i];
for (let j = i + 1; j < yList.length; j++) {
let Y2 = yList[j];
let side = Math.abs(Y1 - Y2);
let X2 = X1 + side;
let p1 = X2 + "#" + Y1
let p2 = X2 + "#" + Y2
if (points.has(p1) && points.has(p2))
count++;
}
}
}
return count;
}
let X = [ 0, 2, 0, 2 ]
let Y = [ 0, 2, 2, 0 ];
let N = X.length;
console.log(countSquares(X, Y, N));
|
Time Complexity: O(N2).
Auxiliary Space: O(N)
Last Updated :
12 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...