在NxNxN二进制数组中查找仅包含1的最大长方体

时间:2012-03-29 10:31:11

标签: arrays algorithm

给定一个NxNxN二进制数组(只包含0或1),我们如何用非平凡解,即在O(N ^ 3)中得到最大的长方体?

-

Find largest rectangle containing only zeros in an N×N binary matrix与上层维度相同。 另外,在我的例子中,最大的矩形可以“穿过阵列的边缘”,即空间就像是2D矩阵的圆环。

对于2D数组,如果条目是:

00111
00111
11000
00000
00111

'X'描述的解决方案是

00XXX
00XXX
11000
00000
00XXX

我已经完成了NxN二进制数组的计算,并按照http://tech-queries.blogspot.de/2011/03/maximum-area-rectangle-in-histogram.html中的想法找到了O(N ^ 2)中最大矩形问题的解决方案。 但我不知道如何将它应用于3D阵列。

-

解决方案“越过边缘”的3x3x3阵列示例:

111
100
011

111
001
111

011
110
011

解决方案应该是:

1XX
100
0XX

1XX
001
1XX

0XX
110
0XX

2 个答案:

答案 0 :(得分:3)

这里只有O(N ^ 4)。

假设您将cubiod存储在bool cuboid [N] [N] [N]中;

bool array2d[N][N];

for(int x_min = 0; x_min < N; x_min++) {
   //initializing array2d
   for(int y = 0; y < N; y++) {
      for(int z = 0; z < N; z++) {
         array2d[y][z] = true;
      }
   }

   //computation
   for(int x_max = x_min; x_max < N; x_max++) {
      // now we want to find largest cube that
      // X coordinates are equal to x_min and x_max

      // cells at y,z can be used in cube if and only if
      // there are only 1's in cuboid[x][y][z] where x_min <= x <= x_max

      // so lets compute for each cell in array2d,
      // if are only 1's in cuboid[x][y][z] where x_min <= x <= x_max
      for(int y = 0; y < N; y++) {
         for(int z = 0; z < N; z++) {
            array2d[y][z] &= cubiod[x_max][y][z];
         }
      }

      //you already know how to find largest rectangle in 2d in O(N^2)
      local_volume = (x_max - x_min + 1) * find_largest_area(array2d);

      largest_volume = max(largest_volumne, local_volume);
   }
}

您可以使用相同的技巧来计算X维度中的最佳解决方案。只需将问题减少到X-1尺寸。复杂性:O(N ^(2 * X-2))。

答案 1 :(得分:3)

该溶液具有O(N 3 log 2 N)复杂性(可以优化为O(N 3 log N))。将需要额外的整数数组,大小为2 * 8 * N 3

  1. 计算r(i,j,k):对于每个N 2 行,计算所有非零元素的累积和,在找到零元素时重置它。
  2. 使用Golden section search(或斐波纳契搜索)找到最大结果,对K的各种值执行以下步骤。
  3. 计算c(i,j,k):对于每个N 2 列,计算r(i,j,k)> = K的所有元素的累积和,重置它当具有r(i,j,k)this answer。
  4. 对M的各种值执行最后一步,使用黄金分割搜索找到最大结果。
  5. 计算和:对于第3个坐标的每个N 2 值,计算所有元素的累积和,其中c(i,j,k)> = M,当元素与c(i,j,k)&lt;找到了M。计算总和 K M并在必要时更新最佳结果。
  6. 以明显的方式处理数组的“越过边缘”属性:迭代每个索引两次并保持所有累积和不大于N.

    对于多维情况,该算法具有O(N D log D-1 N)时间复杂度和O(D * N D )空间复杂性。


    对O(N 3 log N)

    的优化

    算法的第4步设置M的全局值。如果M的值是在本地确定的,则可以排除此步骤(并且复杂性降低 log N )。

    为此,应该改进第5步。它应该保持一个双端队列(其头部包含M的本地值)和一个堆栈(保持M的所有值的起始位置,从队列中逐出)。

    当c(i,j,k)增加时,它会附加到队列的尾部。

    如果c(i,j,k)减小,则从队列的尾部删除所有较大的值。如果它进一步减少(队列为空),则使用堆栈恢复'sum'值并将相应的'M'值放入队列。

    然后,如果允许增加本地解决方案的值,则可以从队列的头部删除几个元素(并推送到堆栈)。

    对于多维情况,此优化给出了O(N D log D-2 N)的复杂性。