題目描述
給定一個僅包含 0 和 1 的二維二進制矩陣,找出只包含 1 的最大矩形,並返回其面積。
示例:
輸入:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
輸出: 6
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/maximal-rectangle
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
白話題目:
算法:
詳細解釋關注 B站 【C語言全代碼】學渣帶你刷Leetcode 不走丟 https://www.bilibili.com/video/BV1C7411y7gB
C語言完全代碼
//方法二:動態規劃法
//1,建立 dp[iCol] 個元素爲 (left, right, height) 數組, left, right, height爲當前位置最大的左邊(座標),右邊(座標),高
//2,當matrix[i][j]=0時,dp[j](left, right, height)=(0,0,0)
//3,當matrix[i][j]=1時,
// 1)計算高 dp[j].height = dp_old[j].height+1
// 2)計算左邊 dp[j].left = max(dp_old[j].left, iCurLeft) iCurLeft 爲當前位置左邊最近0點的座標
// 3)計算右邊 dp[j].right = min(dp_old[j].right, iCurRight) iCurRight 爲當前位置右邊最近0點的座標
//4,計算當前行所有點的面積,計算最大面積
#define MAX_II(a, b) ((a) > (b) ? (a) : (b))
#define MIN_II(a, b) ((a) < (b) ? (a) : (b))
struct PointInfo {
int iLeft;
int iRight;
int iHeight;
};
int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize){
int i = 0;
int j = 0;
int iRow = matrixSize;
int iCol = matrixColSize[0];
int iCurLeft = 0;
int iCurRight = 0;
int iTmpS = 0;
int iMaxS = 0;
struct PointInfo* pDP = NULL;
if((NULL == matrix) || (NULL == matrixColSize) || (0 == matrixSize)) return 0;
//1,初始化動態規劃數組
pDP = (struct PointInfo*)malloc(sizeof(struct PointInfo) * (iCol + 1));
memset(pDP, 0x00, sizeof(struct PointInfo) * (iCol + 1));
for(j = 0; j <= iCol; j++)
{
pDP[j].iLeft = 0;
pDP[j].iRight = iCol;
pDP[j].iHeight = 0;
}
//2,遍歷數組
for(i = 1; i <= iRow; i++)
{
iCurLeft = 0;
for(j = 1; j <= iCol; j++)
{
//3,計算高
if(matrix[i - 1][j - 1] == '0')
{
pDP[j].iHeight = 0;
}
else
{
pDP[j].iHeight += 1;
}
//4,計算左邊
if(matrix[i - 1][j - 1] == '0')
{
pDP[j].iLeft = 0;
iCurLeft = j;
}
else
{
pDP[j].iLeft = MAX_II(pDP[j].iLeft, iCurLeft);
}
}
iCurRight = iCol;
for(j = iCol; j > 0; j--)
{
//5,計算右邊
if(matrix[i - 1][j - 1] == '0')
{
pDP[j].iRight = iCol;
iCurRight = j - 1;
}
else
{
pDP[j].iRight = MIN_II(pDP[j].iRight, iCurRight);
}
//6,計算面積,並找到最大面積
iTmpS = (pDP[j].iRight - pDP[j].iLeft) * pDP[j].iHeight;
iMaxS = MAX_II(iTmpS, iMaxS);
}
}
//7,釋放空間
free(pDP);
return iMaxS;
}
/*
//方法一:動態規劃法
//1,建立 dp[iRow][iCol] 個元素爲 (m, n) 數組, m、n爲當前位置能夠達到最大矩形的行、列
//2,dp[iRow][iCol]的 (m,n) 有兩組值,一個是 (dp[iRow][iCol-1].m, dp[iRow-1][iCol-1].n + 1)
// 一個是 (dp[iRow-1][iCol].m+1, dp[iRow-1][iCol].n) 計算兩組面積,哪個大用哪個
//3,優化後發現,只需要 dp[iCol] 就能夠滿足要求
#define MAX_III(a, b, c) ((a) > ((b) > (c) ? (b) : (c)) ? (a) : ((b) > (c) ? (b) : (c)))
#define MAX_II(a, b) ((a) > (b) ? (a) : (b))
#define MIN_II(a, b) ((a) < (b) ? (a) : (b))
int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize){
int i = 0;
int j = 0;
int iRow = matrixSize;
int iCol = matrixColSize[0];
int iTmpS_R = 0;
int iTmpS_C = 0;
int iTmpS = 0;
int iMaxS = 0;
int** pDP = 0;
if((NULL == matrix) || (NULL == matrixColSize) || (0 == matrixSize)) return 0;
//1,初始化動態規劃數組
pDP = (int**)malloc(sizeof(int*) * (iCol + 1));
for(j = 0; j <= iCol; j++)
{
pDP[j] = (int*)malloc(sizeof(int) * 2);
memset(pDP[j], 0x00, sizeof(int) * 2);
}
//2,遍歷數組
for(i = 1; i <= iRow; i++)
{
for(j = 1; j <= iCol; j++)
{
if(matrix[i - 1][j - 1] == '0')
{
//4,如果 matrix[i,j]==0,則 dp[j]=0
pDP[j][0] = 0;
pDP[j][1] = 0;
}
else
{
if(((pDP[j - 1][0] == 0) && (pDP[j - 1][1] == 0)) ||
((pDP[j][0] == 0) && (pDP[j][1] == 0)))
{
if((pDP[j - 1][0] == 0) && (pDP[j - 1][1] == 0))
{
//5,如果左邊的座標爲(0, 0)
pDP[j][0] = pDP[j][0] + 1;
pDP[j][1] = 1;
}
if((pDP[j][0] == 0) && (pDP[j][1] == 0))
{
//6,如果下面一個座標爲(0, 0)
pDP[j][0] = 1;
pDP[j][1] = pDP[j - 1][1] + 1;
}
iTmpS = pDP[j][0] * pDP[j][1];
iMaxS = MAX_II(iMaxS, iTmpS);
}
else
{
//7,當左邊和右邊都有值時,如何確定(m, n)
if((pDP[j-1][0] > pDP[j][0] + 1) && (pDP[j][1] > pDP[j - 1][1] + 1))
{
pDP[j][0] = pDP[j][0] + 1;
pDP[j][1] = pDP[j - 1][1] + 1;
iTmpS = pDP[j][0] * pDP[j][1];
iMaxS = MAX_II(iMaxS, iTmpS);
}
else if(pDP[j-1][0] > pDP[j][0] + 1)
{
pDP[j][0] = pDP[j][0] + 1;
pDP[j][1] = pDP[j][1];
iTmpS = pDP[j][0] * pDP[j][1];
iMaxS = MAX_II(iMaxS, iTmpS);
}
else if(pDP[j][1] > pDP[j - 1][1] + 1)
{
pDP[j][1] = pDP[j - 1][1] + 1;
pDP[j][0] = pDP[j - 1][0];
iTmpS = pDP[j][0] * pDP[j][1];
iMaxS = MAX_II(iMaxS, iTmpS);
}
else
{
//7,求當前位置從左邊計算的面積,和從下面計算的面積
iTmpS_R = (pDP[j - 1][0]) * (pDP[j - 1][1] + 1);
iTmpS_C = (pDP[j][0] + 1) * (pDP[j][1]);
if(iTmpS_R > iTmpS_C)
{
pDP[j][0] = pDP[j - 1][0];
pDP[j][1] = pDP[j - 1][1] + 1;
}
else
{
pDP[j][0] = pDP[j][0] + 1;
pDP[j][1] = pDP[j][1];
}
//8,計算最大面積
iMaxS = MAX_III(iMaxS, iTmpS_R, iTmpS_C);
}
}
}
if(i > 5)
printf("[1][i=%d][j=%d][val=%c][%d, %d]\n", i, j, matrix[i - 1][j - 1], pDP[j][0], pDP[j][1]);
}
}
//9,釋放空間
for(j = 0; j <= iCol; j++)
{
free(pDP[j]);
}
free(pDP);
return iMaxS;
}
*/