刷题85. Maximal Rectangle

佐手、 提交于 2020-02-27 09:19:51

一、题目说明

题目,85. Maximal Rectangle,计算只包含1的最大矩阵的面积。难度是Hard!

二、我的解答

看到这个题目,我首先想到的是dp,用dp[i][j]表示第i行第j列元素向右下角计算的最大面积。后来发现从dp[i+1][j]dp[i][j+1]dp[i+1][j+1]计算dp[i][j]几乎没有任何规律可循。

然后,我就想用down_dp[i][j]right_dp[i][j]两个dp,但遗憾的是还是没成功。

后面看了大神的写法,其实down_dp[i][j]然后“向右找同一行”计算即可。代码如下:

class Solution{
    public:
        int maximalRectangle(vector<vector<char>>& matrix){
            if(matrix.empty()) return 0;
            int m = matrix.size();
            int n = matrix[0].size();
            
            vector<vector<int>> down_dp(m,vector<int>(n,0));
            int result = 0;
            //最后一行 
            for(int j=n-1;j>=0;j--){
                if(matrix[m-1][j]=='0'){
                    down_dp[m-1][j] = 0;
                }else if(j==n-1){
                    down_dp[m-1][j] =  1; 
                    result = max(1,result);
                }else{
                    down_dp[m-1][j] =  1;
                    result = max(1,result);
                    int tmp = 1;
                    for(int t=j+1;t<n;t++){
                        if(down_dp[m-1][t]>0){
                            tmp++;
                            result = max(tmp,result);
                        }else{
                            break;
                        }
                    }   
                }
            }
            
            //最后一列 
            for(int i=m-1;i>=0;i--){
                if(matrix[i][n-1]=='0'){
                    down_dp[i][n-1] = 0;
                }else if(i==m-1){
                    down_dp[i][n-1] =  1; 
                    result = max(1,result);
                }else{
                    down_dp[i][n-1] =  down_dp[i+1][n-1] + 1;
                    result = max(down_dp[i][n-1],result);
                }
            }

            for(int j=n-1;j>=0;j--){//列 
                for(int i=m-2;i>=0;i--){
                    if(matrix[i][j]=='0'){
                        down_dp[i][j] = 0;
                    }else if(matrix[i][j]=='1'){
                        down_dp[i][j] = down_dp[i+1][j] + 1;
                        result = max(down_dp[i][j],result);
                        int temp = 1,curMin=down_dp[i][j],curMax = down_dp[i][j];
                        
                        //向右找同一行
                        for(int t=j+1;t<n;t++){
                            if(down_dp[i][t]>0){
                                temp++;
                                curMin = min(curMin,down_dp[i][t]);
                                curMax = temp * curMin;
                                result = max(curMax,result);
                            }else{
                                break;
                            }
                        } 
                    }
                }
            }
                                    
            return result;
        }
};

性能如下:

Runtime: 28 ms, faster than 45.92% of C++ online submissions for Maximal Rectangle.
Memory Usage: 11.1 MB, less than 61.11% of C++ online submissions for Maximal Rectangle.

三、优化措施

上面代码,先计算最后一行,最后一列,然后向上计算。其实完全可以合并起来的。

class Solution{
    public:
        int maximalRectangle(vector<vector<char>>& matrix){
            if(matrix.empty()) return 0;
            int m = matrix.size();
            int n = matrix[0].size();
            
            vector<vector<int>> down_dp(m,vector<int>(n,0));
            int result = 0;

            for(int j=n-1;j>=0;j--){//列 
                for(int i=m-1;i>=0;i--){
                    if(matrix[i][j]=='0'){
                        down_dp[i][j] = 0;
                    }else if(matrix[i][j]=='1'){
                        if(i<m-1){
                            down_dp[i][j] = down_dp[i+1][j] + 1;
                        } else{
                            down_dp[i][j] = 1;
                        }
                        
                        result = max(down_dp[i][j],result);
                        int temp = 1,curMin=down_dp[i][j],curMax = down_dp[i][j];
                        
                        //向右找同一行
                        for(int t=j+1;t<n;t++){
                            if(down_dp[i][t]>0){
                                temp++;
                                curMin = min(curMin,down_dp[i][t]);
                                curMax = temp * curMin;
                                result = max(curMax,result);
                            }else{
                                break;
                            }
                        } 
                    }
                }
            }
                                    
            return result;
        }
};
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!