• Maximal Rectangle [leetcode] 的三种思路


    第一种方法是利用DP。时间复杂度是 O(m * m * n)

    dp(i,j):矩阵中同一行以(i,j)结尾的所有为1的最长子串长度

    代码例如以下:

        int maximalRectangle(vector<vector<char> > &matrix) {
            int m = matrix.size();
            if (m == 0) return 0;
            int n = matrix[0].size();
            if (n == 0) return 0;
            vector<vector<int>> dp(m, vector<int>(n));
            int maxArea = 0;
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (matrix[i][j] == '0') continue;
                    dp[i][j] = (j == 0 ? 1 : dp[i][j - 1] + 1);
                    int minX = dp[i][j];
                    for (int k = 1; k <= i + 1; k++)
                    {
                        minX = min(minX, dp[i - k + 1][j]);
                        maxArea = max(maxArea, minX * k);
                    }
                }
            }
            return maxArea;
        }


    另外一种方法

    来自https://oj.leetcode.com/discuss/5198/a-o-n-2-solution-based-on-largest-rectangle-in-histogram

    事实上这里和 Largest Rectangle in Histogram是类似的,

    之前的dp(i,j)保存以第i行。第j列结尾的,同一行中连续1的个数;那么这里我们用一个数组x,使x[j]保存当前行第j列中的连续1的个数。之后按行遍历,每一行都按Largest Rectangle in Histogram的算法处理一遍

    代码例如以下:复杂度为O(m*n)

        int maximalRectangle(vector<vector<char> > &matrix) {
            int m = matrix.size();
            if (m == 0) return 0;
            int n = matrix[0].size();
            if (n == 0) return 0;
            vector<int> height(n);
            int maxArea = 0;
            for (int i = 0; i < m; i++)
            {
                vector<int> index;
                for (int j = 0; j < n; j++)
                {
                    if (matrix[i][j] == '0') height[j] = 0;
                    else height[j] ++;
                    while (index.size() && height[j] <= height[index.back()])
                        maxArea = max(getArea(height, index, j), maxArea);
                    index.push_back(j);
                }
                while (index.size())
                    maxArea = max(getArea(height, index, height.size()), maxArea);
            }
            return maxArea;
        }
        
        int getArea(vector<int> &height, vector<int>& index, int start)
        {
            int areaH = height[index.back()];
            index.pop_back();
            int end = index.empty() ? -1 : index.back();
            return (start - end - 1) * areaH;
        }

    第三种方法:

    利用极值http://hi.baidu.com/mzry1992/item/030f9740e0475ef7dc0f6cba

    H[i][j] = 0                    matrix[i][j] = '0'

                H[i-1][j] + 1     matrix[i][j] = '1'

    L[i][j] = max{L[i-1][j], 第i行左边第一个'0'的位置+1}

    R[i][j] = min{R[i-1][j], 第i行右边第一个'0'的位置-1}

    maxArea = max{maxArea, H[i][j] * (R[i][j] - L[i][j] + 1)}

    因为H,L,R均仅仅用到i-1,j的内容,能够将空间进一步压缩成为O(N)的

    代码例如以下:

        int maximalRectangle(vector<vector<char> > &matrix) {
            int m = matrix.size();
            if (m == 0) return 0;
            int n = matrix[0].size();
            if (n == 0) return 0;
            vector<int> h(n);
            vector<int> l(n);
            vector<int> r(n, n - 1);
            int maxArea = 0, maxL = 0, minR = m - 1;
            for (int i = 0; i < m; i++)
            {
                maxL = 0, minR = n-1;
                for (int j = 0; j < n; j++)
                {
                    if (matrix[i][j] == '0')
                    {
                        h[j] = 0;
                        l[j] = 0;
                        r[j] = n - 1;
                        maxL = j + 1;
                    }
                    else
                    {
                        h[j]++;
                        l[j] = max(l[j], maxL);
                    }
                }
                
                for (int j = n - 1; j >= 0; j--)
                {
                    if (matrix[i][j] == '0')
                    {
                        r[j] = n - 1;
                        minR = j - 1;
                    }
                    else
                    {
                        r[j] = min(r[j], minR);
                        maxArea = max(maxArea, h[j] * (r[j] - l[j] + 1));
                    }
                }
            }
            return maxArea;
        }


  • 相关阅读:
    mysql中给查询结果添加序号
    Mysql如何取当日的数据
    nginx 出现413 Request Entity Too Large问题的解决方法
    Mac 安装Jupyter Notebook
    Python-用xlrd模块读取excel,数字都是浮点型,日期格式是数字的解决办法
    sql-exists、not exists的用法
    sql语句replace函数的使用
    Python-日期格式化
    Python-自动用0补取长度
    Flask-实现下载功能
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6889750.html
Copyright © 2020-2023  润新知