基于leetcode的算法训练:Day10

1、直方图最大矩形面积

题目描述
给定非负整数数组 heights ,数组中的数字用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
题目链接:传送门

其实写过这题了,还是忘记知识点了捏,大概思路应该是分别找index两侧最近的高度小于index的编号。
于是乎,单调栈呼之欲出,从左向右遍历,我们需要求出每一个柱子左边高度小于它的编号.
AC题解

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int ans=0;
        int len=heights.size();
        vector<int>left(len),right(len);//下标为i的左边、右边最近的小于它高度的编号
        stack<int>st;//单调栈
        //左边
        for(int i=0;i<len;i++){
            while(!st.empty()&&heights[i]<=heights[st.top()]){
                st.pop();
            }
            if(st.empty()){
                left[i]=-1;
            }else{
                left[i]=st.top();
            }
            st.push(i);
        }
        while(!st.empty()){
            st.pop();
        }
        //右边
        for(int i=len-1;i>=0;i--){
            while(!st.empty()&&heights[i]<=heights[st.top()]){
                st.pop();
            }
            if(st.empty()){
                right[i]=len;
            }else{
                right[i]=st.top();
            }
            st.push(i);
        }
        //计算最大值
        for(int i=0;i<len;i++){
            int temp=(right[i]-left[i]-1)*heights[i];
            //printf("%d %d w=%d\n",left[i],right[i],right[i]-left[i]-1);
            if(temp>ans){
                ans=temp;
            }
        }
        return ans;
    }
};

WA暴力超时题解
暴力解法是两层遍历,但是时间复杂度比较高,会超时

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int ans=0;
        int len=heights.size();
        //以index为中点,两边扩散的最长不下降编号left right
        for(int i=0;i<len;i++){
            int h=heights[i];
            int temp=h;
            if(temp>ans){
                ans=temp;
            }
            for(int j=i+1;j<len;j++){
                if(heights[j]<h){
                    h=heights[j];
                }
                temp=(j-i+1)*h;
                if(temp>ans){
                    ans=temp;
                }
            }
        }
        return ans;
    }
};

2、矩阵种最大的矩形

题目描述
给定一个由 0 和 1 组成的矩阵 matrix ,找出只包含 1 的最大矩形,并返回其面积。
注意:此题 matrix 输入格式为一维 01 字符串数组。
题目链接:传送门

AC代码
思路同上一题,只不过有点特殊的地方在于先遍历每一列,对该列构建出上一题的heights,用单调栈求取上边界up和下边界down,计算该列产生的最大矩形,如是遍历每一列即可得到矩阵的最大矩形~

class Solution {
public:
    int maximalRectangle(vector<string>& matrix) {
        int ans=0;
        //图像处理课上的编程题~( ̄▽ ̄)~*
        int row=matrix.size();
        if(row==0){
            return ans;
        }else{
            int col=matrix[0].length();
            if(col==0){
                return ans;
            }
            //将每一列视作上一个问题:数组的最大矩形
            vector<int>up(row),down(row),heights(row);
            stack<int>st;
            int temp;
            for(int i=0;i<col;i++){
               //首先统计高度
               fill(heights.begin(),heights.end(),0);
               for(int j=0;j<row;j++){
                   int ii=i;
                   while(matrix[j][ii]!='0'){
                       heights[j]++;
                       ii++;
                       if(ii>=col){
                           break;
                       }
                   }
               }
               //接着计算上边界
               for(int j=0;j<row;j++){
                   while(!st.empty()&&heights[j]<=heights[st.top()]){
                       st.pop();
                   }
                   if(st.empty()){
                       up[j]=-1;
                   }else{
                       up[j]=st.top();
                   }
                   st.push(j);
               } 
               while(!st.empty())st.pop();
               //计算下边界
               for(int j=row-1;j>=0;j--){
                   while(!st.empty()&&heights[j]<=heights[st.top()]){
                       st.pop();
                   }
                   if(st.empty()){
                       down[j]=row;
                   }else{
                       down[j]=st.top();
                   }
                   st.push(j);
               } 
               while(!st.empty())st.pop();
               //计算当前列的最大矩形
               for(int j=0;j<row;j++){
                   temp=(down[j]-up[j]-1)*heights[j];
                   //printf("以(%d,%d)为中心,%d,%d,h=%d\n",j,i,up[j],down[j],heights[j]);
                   if(temp>ans){
                       ans=temp;
                   }
               }
            }
            return ans;
        }
    }
};

你可能感兴趣的:(算法笔记入门,算法,leetcode)