學渣帶你刷Leetcode0085最大矩形

題目描述

給定一個僅包含 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;
}

*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章