【leetcode】Maximal Rectangle (hard)★

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

 

找到01矩形中最大的全1子矩阵。

 

我自己的思路:

      我先用一个跟输入相同大小的矩阵numInCol 存储从当前位置开始向下有多少连续的1。

  如   

1 0 1

0 1 1

1 1 1

其numInCol 是

1 0 3

0 2 2

1 1 1

然后用一个变量tmpans来记录以某个位置开始,其右下矩形的最大全1矩阵的大小。

方法是如果当前位置是1,则用1 * numInCol[当前位置]     即只有这一列的大小

         如果其后面紧接着的位置也是1,则用 2 * (这两列中连续1高度小的值)  即这两列的矩形大小

         如果其后面紧接着的位置也是1,则用 3 * (这三列中连续1高度小的值)  即这三列的矩形大小

         ........................

         依次类推

#include <iostream>

#include <vector>

#include <algorithm>

#include <queue>

#include <stack>

using namespace std;



class Solution {

public:

    int maximalRectangle(vector<vector<char> > &matrix) {

        if(matrix.empty())

            return 0;



        int row = matrix.size();

        int col = matrix[0].size();

        int ans = 0;



        vector<vector<int> > numInCol(row, vector<int>(col, 0));

        int tmpans = 0;



        //对每一列

        for(int j = 0; j < col; j++)

        {

            numInCol[row - 1][j] = (matrix[row - 1][j] == '1') ? 1 : 0;

            for(int i = row - 2; i >= 0; i--)

            {

                if(matrix[i][j] == '1')

                {

                    numInCol[i][j] = numInCol[i + 1][j] + 1;

                }

            }

        }



        //对整个矩阵

        for(int i = row - 1; i >= 0; i--)

        {

            tmpans = numInCol[i][col - 1];

            ans = max(ans, tmpans);

            for(int j = col - 2; j >= 0; j--)

            {

                int jj = j;

                int len = 1;

                int minlen = numInCol[i][j];

                while(jj < col && matrix[i][jj] == '1')

                {

                    minlen = min(minlen, numInCol[i][jj]);

                    tmpans = max(tmpans, len * minlen);

                    ans = max(ans, tmpans);

                    jj++;

                    len++;



                }

            }

        }



        return ans;

    }

};



int main()

{

    Solution s;

    vector<vector<char> > matrix(4, vector<char>(5, '0'));

    matrix[0][1] = '1';

    matrix[0][2] = '1';

    matrix[0][3] = '1';

    matrix[1][1] = '1';

    matrix[1][2] = '1';

    matrix[2][1] = '1';

    matrix[2][2] = '1';

    matrix[2][3] = '1';



    int ans = s.maximalRectangle(matrix);



    return 0;

}

 

网上的答案,整体的思路差不多,也是通过一列列的数据来判断,但是并没有像我一样,把所有的值都存下来,而是只存了一行的列信息,每到新的一行再更新,这样空间少了很多。其次,没有像我这样每次都循环后面的列是否为1,而是利用栈,如果高度是递增的就先不计算最大矩形而是把信息压栈,等到遇到高度减少的时候再依次计算这一段的最大矩形。

class Solution {

public:

    int maximalRectangle(vector<vector<char>> &matrix) {

        if (matrix.empty()) return 0;

        int rows = matrix.size();

        int cols = matrix[0].size();

        int maxArea = 0;

        vector<int> heights(cols + 1, 0);

        vector<int> stack;

        for (int i = 0; i < rows; i++) {

            stack.clear();

            for (int j = 0; j < cols + 1; j++) {

                if (j < cols) {

                    if (matrix[i][j] == '1') {

                        heights[j]++;

                    } else {

                        heights[j] = 0;

                    }

                }

                if (stack.empty() || heights[j] >= heights[stack.back()]) {

                    stack.push_back(j);

                    continue;

                }

                while (!stack.empty() && heights[j] < heights[stack.back()]) {

                    int top = stack.back();

                    stack.pop_back();

                    int begin = stack.empty() ? 0 : stack.back() + 1;

                    int area = heights[top] * (j - begin);

                    if (area > maxArea) maxArea = area;

                }

                stack.push_back(j);

            }

        }

        return maxArea;

    }

};

 

你可能感兴趣的:(LeetCode)