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; } };