LeetCode 84. 柱状图中最大的矩形 85. 最大矩形 221. 最大正方形

LeetCode 

84. 柱状图中最大的矩形

这道题的思路很明确,首先遍历整个数组,找到数值最小元素的位置和值,那么包含这个位置的矩形的最大高度只能是这个最小值,矩形的宽度最大为整个数组的长度,能够存在的更大的矩形只能是不包含这个位置的其他矩形,即在最小位置的左侧和右侧分别进行以上操作,直到数组边界位置,用递归来解决,不断松弛最大矩形的面积。

参考快速排序的时间复杂度,算法时间复杂度为O(nlogn).

class Solution {
public:
    void dfs(vector<int>& heights,int &ans,int l,int r)
    {
        int minn=-1,minid=1;
        for(int i=l;i<=r;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        ans=max(ans,minn*(r-l+1));
        if(minid-1>=l)dfs(heights,ans,l,minid-1);
        if(minid+1<=r)dfs(heights,ans,minid+1,r);
        return;
    }
    int largestRectangleArea(vector<int>& heights) {
        int n=heights.size();
        int ans=0;
        if(n==0)return ans;
        int l=0,r=n-1;
        int minn=-1,minid=-1;
        for(int i=0;i<n;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        ans=max(ans,minn*(r-l+1));
        if(minid-1>=0)dfs(heights,ans,l,minid-1);
        if(minid+1<n)dfs(heights,ans,minid+1,r);
        return ans;
    }
};

85. 最大矩形

这道题需要进行一个预处理,首先从倒数第二行开始直到第一行,如果matrix[i][j]=1,那么matrix[i][j]+=matrix[i+1][j],即通过o(nm)的预处理来获得每个位置及其下方连续的1的个数,预处理完之后我们可以发现,每一行都形成了上一题中的柱状图数组,那么调用n次柱状图数组即可求得最大面积。

算法的时间复杂度为O(nmlog(m))

class Solution {
public:
    void dfs(vector<int>& heights,int &ans,int l,int r)
    {
        int minn=-1,minid=1;
        for(int i=l;i<=r;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        ans=max(ans,minn*(r-l+1));
        if(minid-1>=l)dfs(heights,ans,l,minid-1);
        if(minid+1<=r)dfs(heights,ans,minid+1,r);
        return;
    }
    int largestRectangleArea(vector<int>& heights) {
        int n=heights.size();
        int ans=0;
        if(n==0)return ans;
        int l=0,r=n-1;
        int minn=-1,minid=-1;
        for(int i=0;i<n;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        ans=max(ans,minn*(r-l+1));
        if(minid-1>=0)dfs(heights,ans,l,minid-1);
        if(minid+1<n)dfs(heights,ans,minid+1,r);
        return ans;
    }
    int maximalRectangle(vector<vector<char>>& matrix1) {
        int n=matrix1.size();
        if(n==0)return 0;
        int ans=0;
        int m=matrix1[0].size();
        vector<vector<int>> matrix(n);
        for(int i=0;i<n;i++)matrix[i].resize(m);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                matrix[i][j]+=matrix1[i][j]-'0';
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<m;j++)
            {
                if(i==n-1)break;
                if(matrix[i][j]==1)
                {
                    matrix[i][j]+=matrix[i+1][j];
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            ans=max(ans,largestRectangleArea(matrix[i]));
        }
        return ans;
    }
};

221. 最大正方形

这道题同上题一样进行预处理,不同之处在于答案的更新上,在更新ans之前比较当前矩形高度和长度的关系,如果高度大于长度,那么跳出递归(因为后续的高度肯定高于当前高度,后续宽度肯定小于当前宽度,也就是说后续肯定无解),如果高度小于等于长度,那么ans=minheight*minheight,其他同上题一样。

算法的时间复杂度为O(nmlog(m))

class Solution {
public:
    void dfs(vector<int>& heights,int &ans,int l,int r)
    {
        int minn=-1,minid=1;
        for(int i=l;i<=r;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        if(minn<=r-l+1)ans=max(ans,minn*minn);
        else return;
        if(minid-1>=l)dfs(heights,ans,l,minid-1);
        if(minid+1<=r)dfs(heights,ans,minid+1,r);
        return;
    }
    int largestRectangleArea(vector<int>& heights) {
        int n=heights.size();
        int ans=0;
        if(n==0)return ans;
        int l=0,r=n-1;
        int minn=-1,minid=-1;
        for(int i=0;i<n;i++)
        {
            if(minn==-1)
            {
                minn=heights[i];
                minid=i;
            }
            if(minn>heights[i])
            {
                minn=heights[i];
                minid=i;
            }
        }
        if(minn<=r-l+1)ans=max(ans,minn*minn);
        else return 0;
        if(minid-1>=0)dfs(heights,ans,l,minid-1);
        if(minid+1<n)dfs(heights,ans,minid+1,r);
        return ans;
    }
    int maximalSquare(vector<vector<char>>& matrix1) {
        int n=matrix1.size();
        if(n==0)return 0;
        int ans=0;
        int m=matrix1[0].size();
        vector<vector<int>> matrix(n);
        for(int i=0;i<n;i++)matrix[i].resize(m);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                matrix[i][j]+=matrix1[i][j]-'0';
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<m;j++)
            {
                if(i==n-1)break;
                if(matrix[i][j]==1)
                {
                    matrix[i][j]+=matrix[i+1][j];
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            ans=max(ans,largestRectangleArea(matrix[i]));
        }
        return ans;
    }
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值