200214题(柱状图中最大的矩形(辅助栈))

在这里插入图片描述
在这里插入图片描述
思路:两种方法:1.暴力法;2.辅助栈
先来法2:
在这里插入图片描述
此时初始化max_area=0;
在这里插入图片描述
此时max_area=0;
在这里插入图片描述
此时max_area=0;
在这里插入图片描述
此时cur_area=((2-1)-0)*7=7;max_area=7;
在这里插入图片描述
此时cur_area=((2-1)-(-1))*6=12;max_area=12;在这里插入图片描述
此时max_area=12;
在这里插入图片描述
此时cur_area=((3-1)-(-1))*5=20;max_area=20;
理解了思路之后,后续的同理不再画出。
特别需要注意的是:
为了处理最后一根柱子,对heights进行扩充,即:

heights.push_back(0);//为最后一根柱子准备的

时间复杂度:O(n),n个数字每个会被压栈弹栈各一次。
空间复杂度:O(n),用来存放栈中元素。

完整代码如下(这个代码写出来感觉还挺佩服自己的哈哈哈):

#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
		heights.push_back(0);//为最后一根柱子准备的
		stack<int>index_stack, height_stack;
		index_stack.push(-1);
		height_stack.push(-1);
		int max_area = 0;
		int cur_area = 0;
		for (int i = 0; i < heights.size(); i++) {

			while (index_stack.top() != -1)
			{
				if (heights[i] > height_stack.top())
					break;
				else
				{
					int temp_height = height_stack.top();
					height_stack.pop();
					index_stack.pop();
					cur_area = ((i - 1) - index_stack.top())*temp_height;
					max_area = max(cur_area, max_area);
				}
			}
			index_stack.push(i);
			height_stack.push(heights[i]);
		}


		return max_area;
	}
};

再来看法1暴力法:
首先,我们可以想到,两个柱子间矩形的高由它们之间最矮的柱子决定的。
因此,我们可以考虑所有两两柱子之间形成的矩形面积,该矩形的高为它们之间最矮柱子的高度,宽为它们之间的距离,这样可以找到所要求的最大面积的矩形。

时间复杂度:O(n3),我们需要使用 O(n)的时间找到O(n2)枚举出来的所有柱子对之间的最矮柱子。
空间复杂度:O(1),只需要常数空间的额外变量。
代码如下:

class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
		int max_area = 0, cur_area = 0;
		int min_height;
		for (int i = 0; i < heights.size() - 1; i++)
			for (int j = i + 1; j < heights.size(); j++)
			{
				for (int k = i; k <= j; k++)//找出区间[i,j]最矮的柱子
				{
					if (k == i)
						min_height = heights[k];
					else
						min_height = min(min_height, heights[k]);
				}
				cur_area = min_height*(j - i + 1);
				max_area = max(max_area, cur_area);
			}

		return max_area;
	}
};

虽然,暴力法在leetcode中会显示超出时间限制,但是写还是要会写的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值