找到矩阵中可以从一个角移动到另一个角的最大正方形

时间:2015-02-22 22:50:23

标签: arrays algorithm matrix

例如,您有一个0和1的矩阵:

1 1 1 0
1 1 1 0
1 1 1 0
1 1 1 1
0 1 1 1
1 0 1 1

将一个正方形放置在位置(0,0),找到从左上角到右下角移动的所有1的最大正方形的大小。广场只能向下和向右移动,只能在1的元素上移动。

在这个例子中,最大正方形的大小是2.正方形中元素的索引是(0,0),(0,1),(1,0),(1,1)。

我不确定如何解决这个问题。我想首先,你需要找到左上角的所有方块和右下角的所有方块。如果移动是可能的,则这两个位置必须有相同大小的正方形。然后只尝试将左角的大小相等的方块移动到右角的方形。但我不确定如何找到方块并检查它们是否可以移动。

3 个答案:

答案 0 :(得分:1)

您可以使用动态编程。

  1. 我们假设max_size(i, j)是可以留在(i, j)单元格中的最大正方形的大小(可能为0)(保持在其左上角是位于这个单元格中)。我们可以以天真的方式计算这个值(通过迭代地增加正方形的大小并检查它是否与任何0无关)。如果天真的解决方案不可行,我们可以对答案和前缀总和使用二进制搜索,以便每个单元格获得O(log n)个时间。

  2. 让我们说f(i, j)是可以到达(i, j)单元格的最大正方形。基本情况:f(0, 0) = max_size(0, 0)(我们总是可以到达左上角)。对于其他单元格,可以通过以下方式计算(我在这里省略了极端情况):

    for i <- 0 ... n - 1:
        for j <- 0 ... m - 1:
            f(i, j) = min(max_size(i, j), max(f(i - 1, j), f(i, j - 1)))
    
  3. 答案是最大f(i, j)i + f(i, j) - 1 = n - 1j + f(i, j) - 1 = m - 1

  4. 时间复杂度为O(n * m * log(min(n, m)))

答案 1 :(得分:0)

你的第一步是正确的:找到适合右下角和左上角的最大正方形。

然后,从左上方的那个大小的正方形开始。尝试右下角宽度优先的路径。在每个步骤之后,检查方块是否仍然适合,否则减小其大小。然后,您将经常从两个方向(从上方和左方)到达指定地点。继续从那里开始更大的规模(这个统一步骤就是为什么你应该进行广度优先,这也称为&#34;动态编程&#34;)。

在您的示例中,您从(0 0)处的大小为2的数组开始,但是为了演示目的,我们假设您从大小3开始。因此,第0层是(0 0)处大小为3的单个正方形。向下移动没有问题,但是在一些零上移动到正确的步骤,所以你必须减小尺寸。因此,第1层是两个正方形的列表:(1 0)的大小为3,(0 1)的大小为2。下一层:从(0 1)向右移动,需要在(0 2)缩小为1;向下移动(0 1)以及从(1 0)向右移动,两者都从{1}到达,从大小为2,从左边需要缩小到大小2,所以大小为2;向下移动(1 1),缩小为大小2.因此,第2层是三个正方形的列表:(1 0)的大小为2,(2 0)的大小为2的正方形之一(1 1)的大小为1。我认为这足以作为示范。

完成包含触摸右下方的正方形的图层后,您已达到解决方案。当所有正方形的大小均为0时,您可以确定没有解决方案。

答案 2 :(得分:0)

暴力解决方案

如果您的矩阵的大小为N x M,则从左上角到右下角的大小为S x S的正方形的每个路径都是N + M - 2S'步'(向右或向左移动)长,N - S步骤将向下,M - S步骤向右。因此,如果我们忽略矩阵上的值,将会有(N + M - 2S) choose (N - S)个可能的路径。

因此,如果矩阵不是太大,则可以尝试针对给定的方形大小S尝试所有这些路径,并测试它们是否符合方形放置规则(无论是在每个步骤中, square只包含1 s和0 s。)

S1的每个min(N,M)执行此操作,并跟踪S的值,您可以找到至少一个有效路径。

然后,只需取出这些S值中的最大值,即可得到想要的结果。

所以暴力迫使(最终)会给你正确的价值。

优化

当然,这不是那么高效,这将导致大型矩阵的大量运行时间。但我们可以通过研究哪些步骤是不必要的来逐步改进。

给定方形大小的一个有效路径就足够了

如果您找到了给定方块大小S的有效路径,则不必为相同的方块大小寻找更多路径,并且可以跳过测试其他未经测试的方块大小。< / p>

一个无效步骤会杀死整个路径

如果路径的任何步骤导致无效展示位置,则您无需检查其他步骤。你已经知道你无法使用整条路径。

不要做双重工作

具有给定尺寸(N-S) * (M-S)的正方形的S个可能展示位置中的每一个都将成为多条路径的一部分。不是检查每个展示位置的有效性,而是为每个展示位置执行一次,并将结果存储在(N-S) x (M-S)矩阵中。

更大不适合

如果您已经测试了给定方块大小S的所有路径,并且它们都没有效果,那么您根本不必测试更大的S,因为您知道赢了是他们的有效途径。

小一点不会更糟

如果您找到了给定方形大小S的路径,则可以确保所有较小的方块大小也至少有一个有效路径,因此您无需测试它们。 (无论如何,当你正在寻找具有至少一个有效路径的最大S时,你不必这样做。)

平分?

结合上面的两个实现,您将得出结论:按顺序测试大小S不是最佳的,无论是增加还是减少。相反,您可以从中间的某个位置开始,并根据S的结果 - 排除S的所有较小或全部较大的值。是否最适合在中间开始(min(N,M) / 2),我不确定,作为搜索给定S的路径数量(请记住二项式系数公式中的二项式系数公式)上面的“蛮力”部分)取决于S的大小。

并行化

几乎每个级别的强力算法都有几个相互独立的步骤,可以并行执行。

更多?

我确信即使已经完成上述所有操作,即使我现在也想不到任何优化,仍然有更多优化空间。