Brute force is generally split into two (sometimes sequential) parts. The first part is generating all possible candidates for solutions to the problem. The second part is testing them to see if they actually are solutions.
Brute force: Assume your rectangle is m x n. Generate all sub-rectangles of size a x b where a is in {1..m} and b is in {1..n}. Set a maximum
variable to 0. Test all sub-rectangles to see if it is all 0s and 1s. If it is, let maximum = max(maximum, size(sub-rectangle)
. Alternatively simply start by testing the larger sub-rectangles and move towards testing smaller sub-rectangles. As soon as you find a sub-rectangle with all 0s or 1s, stop. The time complexity will be the same because in the worst-case for both methods, you will still have to iterate through all sub-rectangles.
Time complexity:
Let's count the number of sub-rectangles generated at each step.
There are m*n subrectangles of size 1 x 1.
There are (m-1)*n subrectangles of size 2 x 1.
There are m*(n-1) subrectangles of size 1 x 2.
There are (m-1)*(n-1) subrectangles of size 2 x 2.
... < and so forth >
There are (m-(m-1))*(n-(n-1)) subrectangles of size m x n.
Thus the formula for counting the number of subrectangles of size a x b from a larger rectangle of size m x n is simply:
number_of_subrectangles_of_size_a_b = (m-a) * (m-b)
If we imagine these numbers laid out in an arithmetic series we get
1*1 + 1*2 + ... + 1*n + 2*1 + ... + m*n
This can be factored to:
(1 + 2 + ... + m) * (1 + 2 + ... + n)
.
These two arithmetic series converge to the order of O(m2) and O(n2) respectively. Thus generating all sub-rectangles of an m*n rectangle is O(m2n2). Now we look at the testing phase.
After generating all sub-rectangles, testing if each sub-rectangle of size a x b is all 0s or all 1s is O(a * b). Unlike the previous step of generating sub-rectangles of size a x b which scales upwards as a x b decreases, this step increases proportionally with the size of a x b.
e.g.: There is 1 sub-rectangle of size m x n. But testing to see if that rectangle is all 0s or all 1s takes O(m*n) time. Conversely there are m*n sub-rectangles of size 1. But testing to see if those rectangles are all 0s or all 1s takes only O(1) time per rectangle.
What you finally end up for the time complexity is a series like this:
O( (m-(m-1))(n-(n-1))*(mn) + (m-(m-1))(n-(n-2))*m(n-1)... + mn*(m-(m-1))(n-(n-1)) )
Note 2 things here.
The largest term in the series is going to be somewhere close to (m
/ 2)(n / 2)(m / 2) (n / 2) which is O(m2n2)
There are m * n terms total in the series.
Thus the testing phase of the brute-force solution will be O(mn * m2n2) = O(m3n3).
Total time complexity is:
O(generating) + O(testing)
= O(m2n2 + m3n3)
= O(m3n3)
If the area of the given rectangle is say, N, we will have O(N3) time complexity.