1、問題描述
給定一個只包含0、1的二進制二維矩陣,找出只包含1的最大矩形,並返回其最大面積。
示例:
輸入:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
輸出: 6
2、解題思路
思路1:暴力法。列舉所有以爲左上角和右下角頂點的矩形,取其中最大矩形的面積。
時間複雜度:,因爲遍歷所有的頂點兩次,再加上遍歷以這兩個頂點爲對角頂點的矩形面積有需要耗費時間。
空間複雜度:。
思路2:這道題其實和[leetcode - [棧] - 柱狀圖的最大矩形(84)]是一樣的,它只不過是將其擴展爲了二維的,不信看下圖橙色部分:
因此,
(1)對於矩陣中第i行的每個元素,計算從上邊界開始到連續的1的個數,並存儲在矩陣中;
(2)中第行的值看成是柱狀圖的柱子的高度,求柱狀圖的最大矩形面積;
3、代碼實現
/*算法思想:轉換成求柱狀圖的最大矩形,如何轉化?
(1)對於矩陣中第i行的每個元素matrix[i][j],計算從上邊界開始到matrx[i][j]連續的1的個數,並存儲在矩陣h[i][j]中;
(2)h中第i行的值看成是柱狀圖的柱子的高度,求柱狀圖的最大矩形面積;
*/
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int rows = matrix.size();
int cols = rows > 0 ? matrix[0].size() : 0;
vector<vector<int>> h(rows, vector<int>(cols,0));
for(int c = 0; c < cols; c++){
for(int r = 0; r < rows; r++){
if(matrix[r][c] == '0'){
h[r][c] = 0;
}
else if(matrix[r][c] == '1'){
if(r > 0 && matrix[r-1][c] == '1'){
h[r][c] = h[r-1][c] + 1;
}
else{
h[r][c] = 1;
}
}
// cout<<"h["<<r<<"]["<<c<<"]="<<h[r][c]<<endl;
}
}
int area = 0;
for(int i = 0; i < rows; i++){
// cout<<"maxArea["<<i<<"]="<<maxArea(h[i])<<endl;
area = max(area, maxArea(h[i]));
}
return area;
}
int maxArea(vector<int>& height){
int len = height.size();
stack<int> s;
//壓入height[0]的左邊界索引;
s.push(-1);
int maxarea = 0;
for(int i = 0; i < len; i++){
while(s.top() != -1 && height[i] < height[s.top()]){
int top = s.top();
s.pop();
maxarea = max(maxarea, height[top] * (i - s.top() - 1));
}
s.push(i);
}
while(s.top() != -1){
int top = s.top();
s.pop();
maxarea = max(maxarea, height[top] * (len - s.top() - 1));
}
return maxarea;
}
};