遍历数组,以每一个元素作为高,向左右两边拓展,遇到第一个比该元素小的位置停下
图片源自leetcode 力扣
一.暴力解法(超时)
遍历数组,以每一个元素作为高,向左右两边拓展,遇到第一个比该元素小的位置停下
时间复杂度O(n*n)
空间复杂度O(1)
代码:
二.单调栈
单调栈模板:
模板说明:
一共有4种情况:
给定一个数组nums:
(1)vec保存nums每个元素左边第一个比该元素小的元素:
○正序遍历数组:for(int i=0;i<nums.size();i++)
○单调递增栈:st.top()>=nums[i]
(2)vec保存nums每个元素左边第一个比该元素大的元素:
○ 正序遍历数组:for(int i=0;i<nums.size();i++)
○ 单调递减栈:st.top()<=nums[i]
(3)vec保存nums每个元素右边第一个比该元素小的元素:
○ 逆序遍历数组:for(int i=nums.size()-1;i>=0;i--)
○ 单调递增栈:st.top()>=nums[i]
(4)vec保存nums每个元素右边第一个比该元素小的元素:
○ 逆序遍历数组:for(int i=nums.size()-1;i>=0;i--)
○ 单调递增栈:st.top()>=nums[i]
如果vec存放的是下标:
变动两个地方:
○改成nums[st.top]与nums[i]比较
○最后改为st.push(i)
思路:
用两个数组left_min和right_min存放heigts[i]左边和右边第一个比它小的元素的下标
如果不存在返回-1,nums.size()
则以heights[i]为高的最大矩形面积为(right_min[i]-left_min[i]-1)*heights[i]
代码:
矩阵的每一层转换为直方图,传入84题的函数求解:
如果mat[i][j]=0,height[j]=0
如果mat[i][j]=1,height[j]++