暴力破解通常被分为两个(有时是顺序的)部分。第一部分是生成问题的所有可能解决方案的候选项。第二部分是测试这些候选项以查看它们是否实际上是解决方案。
暴力破解:假设您的矩形是m x n。生成所有大小为a x b的子矩形,其中a在{1..m}中,b在{1..n}中。将maximum
变量设置为0。测试所有子矩形以查看它是否全部为0和1。如果是,则让maximum = max(maximum, size(sub-rectangle)
。或者,仅从测试较大的子矩形开始,并向测试较小的子矩形移动。一旦找到一个全为0或1的子矩形,请停止。时间复杂度将相同,因为在两种方法的最坏情况下,您仍然必须遍历所有子矩形。
时间复杂度:
让我们计算每个步骤产生的子矩形的数量。
大小为1 x 1的子矩形有m*n个。
对于大小为2×1的小矩形,有(m-1)×n个。
对于大小为1×2的小矩形,有m×(n-1)个。
对于大小为2×2的小矩形,有(m-1)×(n-1)个。
...等等
对于大小为a×b的子矩形,从大小为m×n的大矩形中计算子矩形的数量的公式是:
number_of_subrectangles_of_size_a_b = (m-a) * (n-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
2n
2)。现在我们看测试阶段。
生成所有子矩形后,测试大小为a x b的每个子矩形是否全为0或全为1的时间复杂度为O(a*b)。与生成大小为a x b的子矩形的前一步骤不同,该步骤随着a x b的增加而成比例地增加。
例如:大小为m x n的子矩形只有1个。但是测试该矩形是否全为0或全为1需要O(m*n)的时间。相反,大小为1的子矩形有m*n个。但是测试这些矩形是否全为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(m2n2)。
该序列总共有 m * n 个项。
因此,暴力解法的测试阶段时间复杂度为 O(mn * m2n2) = O(m3n3)。
总时间复杂度为:
O(generating) + O(testing)
= O(m2n2 + m3n3)
= O(m3n3)
如果给定矩形的面积为N,那么时间复杂度为O(N
3)。