Finding maximum size sub-matrix of all 1's in a matrix having 1's and 0's

前端 未结 4 998
栀梦
栀梦 2020-12-04 13:42

Suppose you are given an mXn bitmap, represented by an array M[1..m,1.. n] whose entries are all 0 or 1. A all-one block is a subarray of the form M[i .. i0, j .. j0] in whi

4条回答
  •  执笔经年
    2020-12-04 14:30

    Here's an O(numCols*numLines^2) algorithm. Let S[i][j] = sum of the first i elements of column j.

    I will work the algorithm on this example:

    M
    1 1 0 0 1 0
    0 1 1 1 0 1
    1 1 1 1 0 0
    0 0 1 1 0 0 
    

    We have:

    S
    1 1 0 0 1 0
    1 2 1 1 1 1
    2 3 2 2 1 1 
    2 3 3 3 1 1
    

    Now consider the problem of finding the maximum subarray of all ones in a one-dimensional array. This can be solved using this simple algorithm:

    append 0 to the end of your array
    max = 0, temp = 0
    for i = 1 to array.size do
      if array[i] = 1 then
        ++temp
      else
        if temp > max then
          max = temp
        temp = 0
    

    For example, if you have this 1d array:

    1 2 3 4 5 6
    1 1 0 1 1 1
    

    you'd do this:

    First append a 0:

    1 2 3 4 5 6 7
    1 1 0 1 1 1 0
    

    Now, notice that whenever you hit a 0, you know where a sequence of contiguous ones ends. Therefore, if you keep a running total (temp variable) of the current number of ones, you can compare that total with the maximum so far (max variable) when you hit a zero, and then reset the running total. This will give you the maximum length of a contiguous sequence of ones in the variable max.

    Now you can use this subalgorithm to find the solution for your problem. First of all append a 0 column to your matrix. Then compute S.

    Then:

    max = 0
    for i = 1 to M.numLines do
      for j = i to M.numLines do
        temp = 0
        for k = 1 to M.numCols do
          if S[j][k] - S[i-1][k] = j - i + 1 then
            temp += j - i + 1
          else
            if temp > max then
              max = temp
            temp = 0
    

    Basically, for each possible height of a subarray (there are O(numLines^2) possible heights), you find the one with maximum area having that height by applying the algorithm for the one-dimensional array (in O(numCols)).

    Consider the following "picture":

       M
       1 1 0 0 1 0 0
    i  0 1 1 1 0 1 0
    j  1 1 1 1 0 0 0
       0 0 1 1 0 0 0
    

    This means that we have the height j - i + 1 fixed. Now, take all the elements of the matrix that are between i and j inclusively:

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

    Notice that this resembles the one-dimensional problem. Let's sum the columns and see what we get:

    1 2 2 2 0 1 0
    

    Now, the problem is reduced to the one-dimensional case, with the exception that we must find a subsequence of contiguous j - i + 1 (which is 2 in this case) values. This means that each column in our j - i + 1 "window" must be full of ones. We can check for this efficiently by using the S matrix.

    To understand how S works, consider a one-dimensional case again: let s[i] = sum of the first i elements of the vector a. Then what is the sum of the subsequence a[i..j]? It's the sum of all the elements up to and including a[j], minus the sum of all those up to and including a[i-1], meaning s[j] - s[i-1]. The 2d case works the same, except we have an s for each column.

    I hope this is clear, if you have any more questions please ask.

    I don't know if this fits your needs, but I think there's also an O(numLines*numCols) algorithm, based on dynamic programming. I can't figure it out yet, except for the case where the subarray you're after is square. Someone might have better insight however, so wait a bit more.

提交回复
热议问题