A viable option is to ignore the dictum to avoid iteration.
First a routine to find the largest length given a fixed width. Use it on the transposed matrix to reverse those dimensions. It works by divide and conquer, so is reasonably fast.
maxLength[mat_, width_, min_, max_] := Module[
{len = Floor[(min + max)/2], top = max, bottom = min, conv},
While[bottom <= len <= top,
conv = ListConvolve[ConstantArray[1, {len, width}], mat];
If[Length[Position[conv, len*width]] >= 1,
bottom = len;
len = Ceiling[(len + top)/2],
top = len;
len = Floor[(len + bottom)/2]];
If[len == bottom || len == top, Return[bottom]]
];
bottom
]
Here is the slower sweep code. We find the maximal dimensions and for one of them we sweep downward, maximizing the other dimension, until we know we cannot improve on the maximal area. The only efficiency I came up with was to increase the lower bounds based on prior lower bounds, so as to make the maxLength calls slightly faster.
maxRectangle[mat_] := Module[
{min, dims = Dimensions[mat], tmat = Transpose[mat], maxl, maxw,
len, wid, best},
maxl = Max[Map[Length, Cases[Map[Split, mat], {1 ..}, 2]]];
maxw = Max[Map[Length, Cases[Map[Split, tmat], {1 ..}, 2]]];
len = maxLength[tmat, maxw, 1, maxl];
best = {len, maxw};
min = maxw*len;
wid = maxw - 1;
While[wid*maxl >= min,
len = maxLength[tmat, wid, len, maxl];
If[len*wid > min, best = {len, wid}; min = len*wid];
wid
];
{min, best}
]
This is better than Sjoerd's by an order of magnitude, being only terrible and not terrible^2.
In[364]:= Timing[maxRectangle[matrix]]
Out[364]= {11.8, {23760, {108, 220}}}
Daniel Lichtblau