Q (Google onsite): given N Points defined by x,y coordinates, find the largest possible rectangle formed with four corner points drawn from the N points.
====analysis
worst input? many points line up along the north and west of a rectangle?
From N points, we get (roughly) NN line segments, actual count is up N(N-1)/2.
Any 3 points forming a right-angle corner is represented as a Corner object with 5 fields (or more)
- 3 Points: clockwise start point, corner point, clockwise end point
- 2 line segments
A FloatingLineSegment object has 2 fields {length, slope}
Any 2 line segments of equal length and slope forming a parallelogram is represented as a Para object having fields (or more):
- 4 Points
- 4 line segments
- 2 FLSs
- a single point representing the central intersection
Each line segment has one FLS and one slope. So we scan the NN line segments to populate some hashmaps.
A hashmap of {FLS -> set of lineSegments}
A hashmap of {slope -> set of FLS }. From any one slope value, we can look up the FLSs of that slope + the FLSs of the opposite slope.
Scan the NN line segments. For each line segment L1, compute the opposite slope. Use slope hashmap to get the FLSs. Use these FLSs to get the line segments perpendicular to L1. Discard any of those line segments not joining L1. This is how to populate .. A hashmap of {lineSegment -> set of Corners}
Scan the NN line segments. For each line segment L1, compute FLS. Use the FLS hashmap to get the other line segments. This is how to populate … A hashmap of {lineSegment -> set of Paras}
Are there more Corners or more Paras? I hope at least one of them is O(NN)
(From NN line segments, we could get a large number of Corners objects. I think the count of Corners is too big if all points line up along some big rectangle. I feel we should start from one corner and try all possible rectangles rooted there, then remove this corner from the search space.)
Solution 1: At any point C1, there are N-1 relevant line segments. Using a hashmap {slope ->?}, it takes up to O(NN) time to identify all Corners at C1. If N-1 is 8, then at most 4×4 such Corners, so worst case O(NN) such corners. For each Corner, check if the opposite corner point exists. This check is O(1). This entire process at C1 takes O(NN).
Overall O(NNN) since there are N points like C1. Average case is much better.
I feel O(NN logN) is possible.
— O(NNN) by Rahul — pick any 3 points, check if they form a corner. If yes, compute the opposite corner and check its existence.
–Idea 3: for the N(N-1)/2 line segments, sort by slope, length, lowest x-coordinate, lowest y-coordinate…?
sorting takes O(NN logN)
–idea 4: group N(N-1)/2 line segments by slope and length.
Within each group, there are up to N points and O(NN) line segments.
— O(NN) solution … wrong!
Pick any 2 points as a pair-of-opposite-corners. Work out the locations of the other 2 corners and check if they exist. This check is O(1).
There are O(NN) such pairs, so overall O(NN).