原題地址
https://leetcode.com/problems/maximal-rectangle/description/
題意
給定一個01矩陣,找出其中最大的由1構成的矩形,返回它的面積。
思路
和上一題最大子方陣類似,同樣是構造一個表格dp,dp[i ][ j]存儲以元素(i,j)為最右下角的矩形的最大相關的信息,方陣的話只需要邊長即可,而這里是矩形,所以我是建了個結構體data,就存水平方向的長度和豎直方向的長度
struct data {
int h;
int v;
};
在逐步構造dp表的過程中,要得到dp[i][j]的值,每次考慮3種情況:
- 水平方向長度為1,只考慮豎直方向上能達到多長。
- 豎直方向長度為1,只考慮水平方向上能達到多長。
- 根據(jù)dp[i-1][j-1]的值,考慮往水平豎直兩個方向同時擴展能達到的最大面積。
取以上3種情況中使得面積最大的那一種情況填入dp[i][j]
代碼
class Solution {
public:
struct data {
int h;
int v;
};
int maximalRectangle(vector<vector<char> >& matrix) {
int row = matrix.size();
int area = 0;
if (row == 0) return 0;
int col = matrix[0].size();
if (col == 0) return 0;
data initial;
initial.h = 0;
initial.v = 0;
vector<vector<data> > dp(row, vector<data>(col, initial));
for (int i = 0; i < row; i++) {
if (matrix[i][0] == '1') {
dp[i][0].h = 1;
if (i == 0) {
dp[i][0].v = 1;
} else {
dp[i][0].v = dp[i - 1][0].v + 1;
}
} else {
dp[i][0].h = 0;
dp[i][0].v = 0;
}
if (dp[i][0].v * dp[i][0].h > area) {
area = dp[i][0].v * dp[i][0].h;
}
}
for (int i = 0; i < col; i++) {
if (matrix[0][i] == '1') {
dp[0][i].v = 1;
if (i == 0) {
dp[0][i].h = 1;
} else {
dp[0][i].h = dp[0][i - 1].h + 1;
}
} else {
dp[0][i].h = 0;
dp[0][i].v = 0;
}
if (dp[0][i].v * dp[0][i].h > area) {
area = dp[0][i].v * dp[0][i].h;
}
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (matrix[i][j] == '0') {
dp[i][j].h = 0;
dp[i][j].v = 0;
continue;
} else {
dp[i][j].h = 1;
dp[i][j].v = 1;
}
int h1 = 1, v1 = 1, h2 = 1, v2 = 1, h3 = 1, v3 = 1;
int index=1;
while(j-index>=0 && matrix[i][j-index]=='1'){
h1++;
index++;
}
index =1;
while(i-index >=0 && matrix[i-index][j]=='1'){
v2++;
index++;
}
int hextend = dp[i - 1][j - 1].h;
int vextend = dp[i - 1][j - 1].v;
for (int k = 1; k <= hextend; k++) {
if (matrix[i][j - k] == '1') {
h3++;
} else {
break;
}
}
for (int k = 1; k <= vextend; k++) {
if (matrix[i - k][j] == '1') {
v3++;
} else {
break;
}
}
if (h3 * v3 >= h2 * v2 && h3 * v3 >= h1 * v1) {
dp[i][j].h = h3;
dp[i][j].v = v3;
} else if (h2 * v2 > h3 * v3 && h2 * v2 > h1 * v1) {
dp[i][j].h = h2;
dp[i][j].v = v2;
} else {
dp[i][j].h = h1;
dp[i][j].v = v1;
}
if (dp[i][j].h * dp[i][j].v > area) {
area = dp[i][j].h * dp[i][j].v;
}
}
}
return area;
}
};