Q: Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing all ones and return its area. See raiserchu’s mail on 12 Sep 13.

Analysis: Each rectangle is identified by 2 vertices, i.e 4 integers. Without loss of generality, We require the “high” corner to have higher x-coordinate and higher y-coordinate than the “low” corner. (We can assume y-axis run upward.) With this nested loop we can iterate over all possible rectangles in a given matrix:

Lock low corner

Move high corner in typewriter (zigzag) steps i.e.

hold highY and move highX step by step

process the (series of) resulting rectangles

increment highY and repeat

Move the lower corner in typewriter steps and repeat

Key observation: any “bad pixel” disqualifies every rectangle containing it.

— My solution 2:

1) Save all bad pixels in SQL table Bad,

indexed by x-coordinate and

indexed by y-ordinate

Table can be in-memory like Gemfire. Many sorted maps (skiplist or RB tree) support range selection. Gelber interviewer showed me how to use a SQL table to solve algo problems.

2) Follow the nested loop to iterate over all possible rectangles, either disqualify it or save/update its area in maxFound. Here’s how to disqualify efficiently:

For each rectangle under evaluation, we have 4 numbers (lowX, lowY) and (highX, highY).

select ANY from Bad where lowX < Bad.x < highX and lowY < Bad.y < highY

If any hit, then rectangle disqualified. In fact all high corners at the same horizontal level disqualify, so in the nested loop we skip ahead to increment highY

3) At end of nested loop, maxFound is the final answer.

— my earlier solution 1:

1) Iterate over all possible rectangles and save them in a SQL table Rec, indexed by the 4 integers. No need to validate each (time-consuming). Next we start elimination

2) Iterate over all bad pixels. For each bad pixel found, delete from Rec where Rec.lowX < X < Rec.highX and Rec.lowY < Y < Rec.highY

Now all remaining rows are valid candidates

3) max ( (x2 – x1)*(y2 – y1) )

— Here’s my partial solution:

We can effectively ignore all the “good pixels”.

1) Look at the x coordinates of all bad pixels. Sort them into an array. Find the largest gap. Suppose it’s between x=22 and x=33. Our candidate rectangle extends horizontally from 23 to 32, exactly. Notice there’s no bad pixel within this vertical band [1].

2) Look at the y coordinates of all bad pixels. Sort them into an array. Find the largest gap. Suppose it’s between y=15 and y=18. Our candidate rectangle extends vertically from 16 to 17, exactly.

[1] This candidate rectangle can expand All the way vertically, though it may give a bigger rectangle

Ditto horizontally.