【问题标题】:Leetcode: Maximal rectangleLeetcode:最大矩形
【发布时间】:2013-08-01 17:56:17
【问题描述】:

我正在尝试解决 LeetCode 中的maximal rectangle problem

我的实现分为两个阶段。 第一阶段建表tabrec。 对于输入矩阵范围内的任何 i 和 j 如果matrix[i][j] == '0',则tabrec[i][j]未定义,否则记录'1'在四个方向(左、右、上、下)的最大扩展。 在第二阶段,我通过遍历行和列来计算最大矩形。 对于每一行,我可以识别同一行中连续的 1。 我还可以找到包含 1 行的最小矩形与之前构建的表格。

这里是代码

class Solution {
    struct Rect {
        int l;
        int r;
        int t;
        int b;
    };

public:
    int maximalRectangle(vector<vector<char> > &matrix) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int row = matrix.size();
        int col = 0;
        if (row) col = matrix[0].size();

        if (!(row && col)) return 0;

        Rect *storage = new Rect[row * col];
        Rect **rectab = new Rect*[row];

        for (int i = 0; i < row; i++)
            rectab[i] = storage + i * col;

        // find the left most 1-extension for each point
        for (int i = 0; i < row; i++) {
            if (matrix[i][0] == '1') rectab[i][0].l = 0;
            for (int j = 1; j < col; j++) {
                if (matrix[i][j] == '1') {
                    if (matrix[i][j - 1] == '1')
                        rectab[i][j].l = rectab[i][j - 1].l;
                    else
                        rectab[i][j].l = j;
                }
            }
        }
        // find the right most 1-extension for each point
        for (int i = 0; i < row; i++) {
            if (matrix[i][col - 1] == '1') rectab[i][col - 1].r = col - 1;
            for (int j = col - 2; j >= 0; j--) {
                if (matrix[i][j] == '1') {
                    if (matrix[i][j + 1] == '1') rectab[i][j].r = rectab[i][j + 1].r;
                    else rectab[i][j].r = j;
                }
            }
        }
        // find the top most 1-extension for each point
        for (int j = 0; j < col; j++) {
            if (matrix[0][j] == '1') rectab[0][j].t = 0;
            for (int i = 1; i < row; i++) {
                if (matrix[i][j] == '1') {
                    if (matrix[i - 1][j] == '1') rectab[i][j].t = rectab[i - 1][j].t;
                    else rectab[i][j].t = i;
                }
            }
        }
        // find the bottom most 1-extension for each point
        for (int j = 0; j < col; j++) {
            if (matrix[row - 1][j] == '1') rectab[row - 1][j].b = row - 1;
            for (int i = row - 2; i >= 0; i--) {
                if (matrix[i][j] == '1') {
                    if (matrix[i + 1][j] == '1') rectab[i][j].b = rectab[i + 1][j].b;
                    else rectab[i][j].b = i;
                }
            }
        }

        int max = 0;
        int i = 0;
        int j = 0;
        while (i < row) {
            while (j < col && matrix[i][j] == '0') j++;
            if (j < col) {
                int el = rectab[i][j].l;
                int er = rectab[i][j].r;
                int et = rectab[i][j].t;
                int eb = rectab[i][j].b;
                j++;
                while (j < col && matrix[i][j] == '1') {
                    Rect *rect = &rectab[i][j];
                    if (el < rect->l) el = rect->l;
                    if (er > rect->r) er = rect->r;
                    if (et < rect->t) et = rect->t;
                    if (eb > rect->b) eb = rect->b;

                    j++;
                }

                if (max < (er - el + 1) * (eb - et + 1))
                    max = (er - el + 1) * (eb - et + 1);

                if (j == col) {
                    i++;
                    j = 0;
                }
            } else {
                i++;
                j = 0;
            }
        }

        delete [] storage;
        delete [] rectab;

        return max;
    }
};

此实现可以通过小数据集测试,而在大数据集测试失败 4 例。

我无法找出问题所在。 我的算法有什么问题(我认为是对的)或我的实现中有一些错误吗?

【问题讨论】:

    标签: algorithm dynamic-programming


    【解决方案1】:

    您的算法存在错误:

            while (j < col && matrix[i][j] == '1') {
                Rect *rect = &rectab[i][j];
                if (el < rect->l) el = rect->l;
                if (er > rect->r) er = rect->r;
                if (et < rect->t) et = rect->t;
                if (eb > rect->b) eb = rect->b;
    
                j++;
            }
    
            if (max < (er - el + 1) * (eb - et + 1))
                max = (er - el + 1) * (eb - et + 1);
    

    在这里,您应该将 if 语句放在 while 循环中。因为有时,您不需要到达当前行的最后 1。看一个例子:

    0 1 1 1 1
    1 1 1 1 0
    

    答案应该是 6,但您的算法将返回 4。

    即使进行了上述更改,它仍然不正确。其实这个问题最好用DP来解决。搜索最大的二维数组和以供参考。

    【讨论】:

    • 感谢您的回答。 “搜索最大的二维数组以供参考”,您能详细说明一下吗?幼稚的最大金额政策当然行不通,例如在您的示例中,总区域的总和不小于任何子二维数组。再次感谢你。 :)
    • @Summer_More_More_Tea 你可以使用一个基于朴素最大和算法的小技巧:如果matrix[i][j]==0,将其设置为-MAX_INT,如果matrix[i][j]= =1,不改变。然后你可以直接应用最大和算法。
    猜你喜欢
    • 2010-09-05
    • 2013-03-05
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多