蛮力通常分为两个(有时是连续的)部分。第一部分是为问题的解决方案生成所有可能的候选者。第二部分是测试它们,看看它们是否真的是解决方案。
蛮力:假设你的矩形是 mx n。生成所有大小为 axb 的子矩形,其中 a 在 {1..m} 中,b 在 {1..n} 中。将maximum
变量设置为 0。测试所有子矩形,看是否全为 0 和 1。如果是,让maximum = max(maximum, size(sub-rectangle)
. 或者,简单地从测试较大的子矩形开始,然后转向测试较小的子矩形。一旦你找到一个全为 0 或 1 的子矩形,就停止。时间复杂度将是相同的,因为在这两种方法的最坏情况下,您仍然必须遍历所有子矩形。
时间复杂度:
让我们计算一下每一步生成的子矩形的数量。
有 m*n 个大小为 1 x 1 的子矩形。
有 (m-1)*n 个大小为 2 x 1 的子矩形。
有 m*(n-1) 个大小为 1 x 2 的子矩形。
有 (m-1)*(n-1) 个大小为 2 x 2 的子矩形。
... <等等>
有 (m-(m-1))*(n-(n-1)) 个大小为 mx n 的子矩形。
因此,从大小为 mxn 的较大矩形计算大小为 axb 的子矩形的数量的公式很简单:
number_of_subrectangles_of_size_a_b = (m-a) * (m-b)
如果我们想象这些数字以算术级数排列,我们会得到
1*1 + 1*2 + ... + 1*n + 2*1 + ... + m*n
这可以被考虑为:
(1 + 2 + ... + m) * (1 + 2 + ... + n)
.
这两个算术级数分别收敛到 O(m 2 ) 和 O(n 2 ) 的数量级。因此生成 m*n 矩形的所有子矩形是 O(m 2 n 2 )。现在我们来看测试阶段。
生成所有子矩形后,测试每个大小为 axb 的子矩形是全 0 还是全 1 为 O(a * b)。与上一步生成大小为 axb 的子矩形(随着 axb 减小而向上缩放)不同,此步骤与 axb 的大小成比例地增加。
例如:有 1 个大小为 mx n 的子矩形。但是测试该矩形是全 0 还是全 1 需要 O(m*n) 时间。相反,有 m*n 个大小为 1 的子矩形。但是测试这些矩形是全 0 还是全 1 只需要每个矩形 O(1) 时间。
您最终得到的时间复杂度是这样的系列:
O( (m-(m-1))(n-(n-1))*(mn) + (m-(m-1))(n-(n-2))*m(n-1)... + mn*(m-(m-1))(n-(n-1)) )
注意这里的两件事。
该系列中最大的项将接近 (m / 2)(n / 2)(m / 2) (n / 2) ,即 O(m 2 n 2 )
该系列共有 m * n 项。
因此,蛮力解决方案的测试阶段将是 O(mn * m 2 n 2 ) = O(m 3 n 3 )。
总时间复杂度为:
O(generating) + O(testing)
= O(m2n2 + m3n3)
= O(m3n3)
如果给定矩形的面积是 N,我们将有 O(N 3 ) 时间复杂度。