📌  相关文章
📜  全为 1 的最大尺寸矩形二进制子矩阵 |设置 2

📅  最后修改于: 2022-05-13 01:57:09.342000             🧑  作者: Mango

全为 1 的最大尺寸矩形二进制子矩阵 |设置 2

给定一个大小为N*M的二进制矩阵mat[][] ,找到最大大小为全 1 的矩形二进制子矩阵。

例子:

方法:此方法使用直方图中最大矩形区域的概念。但是获得每行最大面积的方法与 Set-1 不同。

插图:

这种方法可以分为两部分:

  • 计算每行的直方图高度作为基础。
    • 运行循环以遍历行。
    • 现在如果当前行不是第一行,则更新该单元格的高度,如下所示,
      • 如果mat[i][j]不为零,则matrix[i][j] = matrix[i-1][j] + matrix[i][j]
      • 否则mat[i][j] = 0
  • 以每行为基数,计算直方图中最大矩形面积为 1。
    • 首先计算每行的高度作为基数,如上所述。
    • 创建两个数组nextSmallereElemen[]prevouSmallerElement[]分别存储前一个较小元素和下一个较小元素的索引。请参阅本文以查找上一个和下一个较小的元素。
    • 现在对于每个元素,通过将第 j 个元素作为 nextSmallereElemen[j] 和 prevouSmallerElement[j] 范围内的最小值并将其乘以nextSmallereElemen[j]prevouSmallerElement [j] 的差来计算面积。
      • 因此,高度将是给定输入数组中的第 j 个元素。宽度将是, breadth = nextSmallereElemen[j] – previousSmallerElement[j]
    • 最后,找到所有区域中的最大值以获得所需的最大区域。
  • 找到所有行中的最大面积,这将是矩形所需的面积。

以下是上述方法的实现:

C++
// C++ code for the above approach:
 
#include 
using namespace std;
 
// Function to find next smaller element
vector nextsmallerelement(vector& arr,
                               int n)
{
 
    stack st;
 
    // For the elements which dont have
    // next smaller element ans will be -1
    st.push(-1);
 
    // Store indices in output
    vector right(n);
 
    // Start from last index
    for (int i = n - 1; i >= 0; i--) {
 
        // If top element is sorted then
        // no need to do anyrhing, just store
        // the answer and push the
        // current element in stack
        if ((st.top() != -1)
            && arr[st.top()] < arr[i]) {
            right[i] = st.top();
            st.push(i);
        }
        else {
            while ((st.top() != -1)
                   && arr[st.top()]
                          >= arr[i]) {
                st.pop();
            }
            right[i] = st.top();
            st.push(i);
        }
    }
    return right;
}
 
// Function to find previous smaller element
vector previousmallerelement(vector& arr,
                                  int n)
{
    stack st;
    st.push(-1);
    vector left(n);
 
    // Start from first index
    for (int i = 0; i < n; i++) {
        if ((st.top() != -1)
            && arr[st.top()] < arr[i]) {
            left[i] = st.top();
            st.push(i);
        }
        else {
            while ((st.top() != -1)
                   && arr[st.top()]
                          >= arr[i]) {
                st.pop();
            }
            left[i] = st.top();
            st.push(i);
        }
    }
    return left;
}
 
// Function to get the maximum area
// considering each row as the histogram base
int getMaxArea(vector& arr, int n)
{
    vector right(n);
    right = nextsmallerelement(arr, n);
 
    // Find the smallest element than
    // curr element in right side
 
    vector left(n);
    left = previousmallerelement(arr, n);
 
    // Find the smallest element
    // than curr element in left side
    int maxarea = INT_MIN;
 
    // Now the left and right vector have
    // index of smallest elemnt in left and
    // right respetively, thus the difference
    // of right - left - 1 will give us
    // breadth and thus
    // area = height(curr==arr[i]) * breadth;
    for (int i = 0; i < n; i++) {
        int height = arr[i];
        if (right[i] == -1) {
            right[i] = n;
        }
        int breadth = right[i] - left[i] - 1;
        maxarea = max(maxarea,
                      height * breadth);
    }
    return maxarea;
}
 
// Function to calculate
// the maximum area of rectangle
int maxRectangleArea(vector >& M,
                     int n, int m)
{
 
    // Calculate maxarea for first row
    int area = getMaxArea(M[0], m);
    int maxarea = area;
 
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (M[i][j] != 0) {
 
                // Add heights of previous rows
                // into current
                M[i][j] = M[i][j]
                          + M[i - 1][j];
            }
            else {
 
                // If current height is 0 then
                // don't add previous heights
                M[i][j] = 0;
            }
        }
        maxarea = max(maxarea,
                      getMaxArea(M[i], m));
    }
    return maxarea;
}
 
// Driver code
int main()
{
    int N = 4, M = 4;
    vector > amt = {
        { 0, 1, 1, 0 },
        { 1, 1, 1, 1 },
        { 1, 1, 1, 1 },
        { 1, 1, 0, 0 },
    };
 
    cout << maxRectangleArea(amt, N, M);
    return 0;
}


Javascript


输出
8

时间复杂度: O(N * M)
辅助空间: O(M)