leetcode 84. Largest Rectangle in Histogram 、85. Maximal Rectangle 、221. Maximal Square

84. Largest Rectangle in Histogram

https://www.cnblogs.com/grandyang/p/4322653.html

整体思路是递增不处理,当遇到减少时,计算之前所有大于当前高度的最优解。因为实际上只要遇到比你小的,就不可能以你为高度了。索引之间的差刚好能反应当前栈中高度所覆盖的区域,即宽度。

 

维护一个递增的栈,每次只用以当前栈的index的相对高 * 宽度,宽度就是以当前栈的index的右侧。每次计算的是一个局部最优解。

i--的目的是让比较对象一直停留在这个位置;

push 0的目的是计算所有的栈中剩下的大小;

当前比较的i,实际上只计算i左侧的最优解,所以是i - con.top() - 1,并且con.top()是递增的下一个index。

1.存储一个单调递增的栈

2.如果你不加一个0进去,[1]这种情况就会输出结果0,而不是1

3.单调递增的栈,如果遇到比栈的top小的,就要计算一次。其实可以看到,这个top,从左向top是最大的,top向右也是最大的,所以只能乘以他自己。

注意:这个地方con必须pop(),这样才能找到当前top所属于的高度所覆盖的宽度,比如当前top的值是7,pop出来后stack的top的值可能变成3,覆盖的区域是4,因为stack里面不是3、4、5这样连续的,大概率是一些间隔的。这也就是为什么后面使用i - con.top() - 1 ,而不使用i - index。

 

每次当前位置的height比stack的top小的,就需要计算以stack顶部的height为高度的局部最优解。

算覆盖区域的时候,必是i - con.top(),这个时候你就应该考虑是否-1。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> con;
        int area = 0;
        heights.push_back(0);
        for(int i = 0;i < heights.size();i++){
            if(con.empty() || heights[con.top()] < heights[i])
                con.push(i);
            else{
                int index = con.top();
                con.pop();
                area = max(area,heights[index] * (con.empty() ? i : (i - con.top() - 1)));
                i--;
            }
        }
        return area;
    }
};

 

 

 

85. Maximal Rectangle

http://www.cnblogs.com/grandyang/p/4322667.html

把矩形分成一行一行送入子函数获得每行的最大值,然后再比较各行的最大值获得总的最大值。每行的计算和largest rectangle in histogram是一样的。

送入的每行不是0、1组成,而是每行的高度,这样就转换成了largest rectangle in histogram的问题

class Solution {
public:
    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;
        int res = 0;
        vector<int> input(n);
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++)
                input[j] = (matrix[i][j] == '0' ? 0 : 1 + input[j]);
            res = max(res,maximal(input));
        }
        return res;
    }
    int maximal(vector<int> matrix){
        stack<int> s;
        int res = 0;
        matrix.push_back(0);
        for(int i = 0;i < matrix.size();i++){
            if(s.empty() || matrix[s.top()] < matrix[i])
                s.push(i);
            else{
                int num = s.top();
                s.pop();
                res = max(res,matrix[num] * (s.empty() ? i : (i - s.top() - 1)));
                i--;
            }
        }
        return res;
    }
};

 

 

221. Maximal Square

https://www.cnblogs.com/grandyang/p/4550604.html 解法3

以正方形的右下角进行判断,只用判断左上角,左边和上边。

dp[i][j] 表示到达 (i, j) 位置所能组成的最大正方形的边长。

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if(matrix.empty())
            return 0;
        if(matrix[0].empty())
            return 0;
        int res = 0;
        vector<vector<int> > area(matrix.size(),vector<int>(matrix[0].size(),0));
        for(int i = 0;i < matrix.size();i++){
            for(int j = 0;j < matrix[0].size();j++){
                if(i == 0 || j == 0)
                    area[i][j] = matrix[i][j] - '0'; 
                else if(matrix[i][j] == '1')
                    area[i][j] = min(area[i-1][j-1],min(area[i-1][j],area[i][j-1])) + 1;
                res = max(res,area[i][j]);
            }
        }
        return res*res;
    }
};

 

posted @ 2019-03-12 21:09  有梦就要去实现他  阅读(171)  评论(0编辑  收藏  举报