zoukankan      html  css  js  c++  java
  • Maximal Rectangle&Largest Rectangle in Histogram

    这两天在做leetcode的题目,最大矩形的题目以前遇到很多次了,一直都是用最笨的方法,扫描每个柱子,变换宽度,计算矩形面积,一直都以为就这样O(n2)的方法了,没有想到居然还有研究出了O(n)的算法,真是对GeeksForGeeks大神膜拜啊。

    首先是Largest Rectangle in Histogram这个题目

     1 class Solution {
     2 public:
     3     int largestRectangleArea(vector<int> &height) {
     4         int len=height.size();
     5         if(len<=0) return 0;
     6         stack<int> s;
     7         int j=0,h,w,maxArea;
     8         while(j<len){
     9             if(s.empty()||height[s.top()]<=height[j]) s.push(j++);//栈空或者有大于栈顶的柱,则一直入栈
    10             else {//计算当前范围内的最大矩形面积
    11                 h=height[s.top()];//高度
    12                 s.pop();
    13                 w=s.empty()?j:j-1-s.top();//宽度
    14                 maxArea=max(maxArea,w*h);
    15             }
    16         }
    17         while(!s.empty()){//遍历栈中的元素,考虑宽度也占优势原因
    18             h=height[s.top()];
    19             s.pop();
    20             w=s.empty()?len:len-1-s.top();
    21             maxArea=max(maxArea,w*h);
    22         }
    23         return maxArea;
    24     }
    25 };

    然后是Maximal Rectangle这个题目,考虑到整个矩阵的情况,我们可以把他当成是二维的Largest Rectangle in Histogram,代码如下:

    class Solution {
    public:
        int maximalRectangle(vector<vector<char> > &matrix) {
          int row=matrix.size();
          if(row==0) return 0;
          int column=matrix[0].size();
          if(column==0) return 0;
    
          //计算从当前点开始此行中连续的1的个数
          int ** dpNum=(int**) malloc(sizeof(int *)*row);
          int i,j,k;
          for(i=0;i<row;i++){
            dpNum[i]=(int*)calloc(column,sizeof(int));
            for(j=column-1;j>=0;j--){
              if(matrix[i][j]=='1'){
                if(j==column-1) dpNum[i][j]=1;
                else dpNum[i][j]=1+dpNum[i][j+1];
              } else {
                dpNum[i][j]=0;
              }
            }
          }
    
          //按照最大矩形面积计算,使用一个栈保存中间子矩阵遍历高度。
          int maxArea=0,height=0,width=INT_MAX,currentArea=INT_MAX;
          for(i=0;i<column;i++){
    
            j=0;
            stack<int> s;
            while(j<row){
              if(s.empty()||dpNum[j][i]>=dpNum[s.top()][i]) s.push(j++);
              else {
                width=dpNum[s.top()][i];
                s.pop();
                height=s.empty()?dpNum[j][i]:dpNum[j][i]-s.top()-1;
                maxArea=max(maxArea,width*height);
              }
            }
    
            while(!s.empty()){
                width=dpNum[s.top()][i];
                s.pop();
                height=s.empty()?row:row-s.top()-1;
                maxArea=max(maxArea,width*height);
            }
          }
    
          return maxArea;
        }
    };

    我能说开始的时候我只想到了扫描扫描扫描,很少能考虑到是否有更加高效的方法,真是汗颜啊……

  • 相关阅读:
    云服务器数据库连接(初始密码)
    springboot打jar包正常无法访问页面
    JAVA项目启动正常,无法访问
    vs快捷键大全(转)
    Effective C#(3)
    单元测试之道C#版(1)
    单元测试之道C#版(2)
    从零开始复习股票知识
    A new languageGo
    单元测试之道C#版(3)
  • 原文地址:https://www.cnblogs.com/havePassed/p/3878196.html
Copyright © 2011-2022 走看看