tags:

views:

97

answers:

3

Given n points in a plane , how many squares can be formed ...??

I tried this by calculating the distances between each 2 points , then sort them , and look for the squares in the points with four or more equal distances after verifying the points and slopes.

But this looks like an approach with very high complexity . Any other ideas ...??

I thought dynamic programming for checking for line segments of equal distances might work ... but could not get the idea quite right ....

Any better ideas???

P.S : The squares can be in any manner . They can overlap , have a common side, one square inside another ...

Any links that help my understanding the problem better are appreciable ... If possible please give a sample code to perform the above...

+1  A: 

It looks like O(n^3) to me. A simple algo might be something like:

for each pair of points
    for each of 3 possible squares which might be formed from these two points
        test remaining points to see if they coincide with the other two vertices
Paul R
How do you do the test in `O(n)`? Looks `O(n^4)` to me, unless you have a clever way to prevent the test from being done in `O(n^2)`.
IVlad
IVlad: you only need to test each of n-2 points to see if they coincide with either of the two remaining vertices. Hence the test is O(n).
Paul R
@Paul - then I'm guessing you're assuming you have the distances between each pair of points precomputed, is that correct? You should mention that, it might not be immediately obvious to everyone.
IVlad
Here's an optimization: The points can be sorted by their coordinates in linear time by Radix Sort. The test then becomes a lookup of time O(log(n)). Thus, total time is O(n^2 * log(n)).
Vilx-
Also, when picking pairs, you can halve the runtime by avoiding comparing the same pair twice. It's still the same complexity, but twice faster nevertheless.
Vilx-
@IVlad - if you have 2 points, then calculating the possible locations of the other 2 points can be done mathematically. No need to precompute the distances between every pair of points.
Vilx-
@IVlad: no, I think you're missing the point. Two points define three possible squares, the coordinates of which can be calculated exactly - we're just looking for points which match the vertices, not looking at distances etc.
Paul R
The other answer suggested using hashtables. I guess that's doable too. Add all points to a hashtable and perform your test through that. You'll get pretty close to O(n^2). You could get to a perfect O(n^2) by using a radix tree, but that's a bit more complex to implement.
Vilx-
@Vilx: I guess it depends on whether you're looking for an exact match on the coordinates (i.e.. integer coordinates only) or whether it's a continuous 2D space and you have some kind of matching tolerance (i.e. floating point coordinates).
Paul R
Oh, I get it now. +1.
IVlad
@Paul R - well, the author hasn't specified. :) However I think you could make a data structure that would allow looking up nearby values as well. An index could do it, maybe a radix tree too.
Vilx-
+1  A: 

Let d[i][j] = distances between points i and j. We are interested in a function count(i, j) that returns, as fast as possible, the number of squares that we can draw by using points i and j.

Basically, count(i, j) will have to find two points x and y such that d[i][j] = d[x][y] and check if these 4 points really define a square.

You can use a hash table to solve the problem in O(n^2) on average. Let H[x] = list of all points (p, q) that have d[p][q] = x.

Now, for each pair of points (i, j), count(i, j) will have to iterate H[ d[i][j] ] and count the points in that list that form a square with points i and j.

This should run very fast in practice, and I don't think it can ever get worse than O(n^3) (I'm not even sure it can ever get that bad).

IVlad
Note that the condition `d[i][j] = d[x][y] and d[i][x] = d[j][y] or d[i][y] = d[j][x]` doesn't guarantee that it's a square. You should still check that it is.
Vilx-
@Vilx - true, you should.
IVlad
A: 

Just a thought: if a vertex A is one corner of a square, then there must be vertices B, C, D at the other corners with AB = AD and AC = sqrt(2)AB and AC must bisect BD. Assuming every vertex has unique coordinates, I think you can solve this in O(n^2) with a hash table keying on (distance, angle).

Rafe