关于LeetCode的Largest Rectangle in Histogram的低级解法
在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢?
还是先把题目贴上来吧

题目写的很直观,就是找直方图的最大矩形面积,不知道是受之前的trie tree影响怎么的,感觉树这玩意还真有用,于是就思考呀,还真别说,真想出一种方式,好吧,其实是入了一个大坑,也无妨,记录下来,好歹也是思路历程.....
大概思路这样的:
每次寻找直方图的最小值,记录此时以该最小值,和以其为高度的矩形面积,再将直方图以该最小值为界限,将直方图分成若干份,按照同样思路对每个子直方图继续求解,这样如果把每个直方图作为节点的话,其实也形成了一棵树,不过这树没啥价值,因为本题并不关心得到最大矩形的路径,只要求面积即可,是时候献丑了,代码贴上:
#include <vector>
#include <list>
#include <iostream>
#include <stack>
using namespace std;
class LRTreeNode
{
private:
int getMin()
{
if (right-left == 0)
{
return 0;
}
int min = (*heights)[left];
for (int i=left;i<right;i++)
{
min = (*heights)[i] > min ? min : (*heights)[i];
}
return min;
}
void getMaxArea()
{
maxArea = bottom*(right-left);
}
public:
int left, right;
int bottom;
int min;
int maxArea;
static vector<int>* heights;
vector<LRTreeNode*> lrnv;
LRTreeNode(int bottom,int left,int right)
{
this->left = left;
this->right = right;
this->bottom=getMin()+bottom;
this->min = getMin();
getMaxArea();
}
vector<LRTreeNode*>* genChildren()
{
int left2=left, right2=left;
for (int i = left; i < right; i++)
{
(*heights)[i] -= min; if ((*heights)[i] == 0 )
{
if (right2-left2 != 0)
{
lrnv.push_back(new LRTreeNode(bottom,left2,right2));
}
left2 = i+1;
right2 = i+1;
}
else
{
right2++;
}
}
if (right2 - left2 != 0)
{
lrnv.push_back(new LRTreeNode(bottom, left2, right2));
}
return &lrnv;
}
};
vector<int>* LRTreeNode::heights = NULL;
class LRTree
{
private:
LRTreeNode root;
public:
LRTree(vector<int>& heights) :root(0,0,heights.size())
{ }
int getMaxArea()
{
int max = root.maxArea;
list<LRTreeNode*> st;
vector<LRTreeNode*>* t = root.genChildren();
LRTreeNode* stt;
for (int i = 0; i < t->size(); i++)
{
st.push_back((*t)[i]);
max = max >(*t)[i]->maxArea ? max : (*t)[i]->maxArea;
}
while (st.empty() == false)
{
stt = st.back();
t = stt->genChildren();
st.pop_back();
for (int i = 0; i < t->size(); i++)
{
st.push_back((*t)[i]);
max = max > (*t)[i]->maxArea ? max : (*t)[i]->maxArea;
}
delete stt;
}
return max;
}
}; class Solution {
public:
int largestRectangleArea(vector<int>& heights);
};
int Solution::largestRectangleArea(vector<int>& heights)
{
LRTreeNode::heights = &heights;
LRTree t(heights);
return t.getMaxArea();
} int main()
{
vector<int> t = {1,2,3,4,5};
Solution s;
cout << s.largestRectangleArea(t);
return 0;
}
代码里面有几个值得注意的问题:
1.按照之前所说的思路,每个节点都得存储一个子直方图,这样并非最好方法,试想如果直方图为n,依次增加,则空间复杂度为O(n^2),故采用了所有节点共用一个直方图,每个节点存储左右界限即可,也就是LRTreeNode的left,right;
2.在每次的子直方图中都减去了底部部分,所以最终的直方图数据会被变化。
该种方法虽然采用了分治的思想,但其本质其实是遍历了所有的可能的矩形,其实效果并不好,由于最小值的多次寻找增加了复杂度,但作为思路历程,还是一并记录。
关于LeetCode的Largest Rectangle in Histogram的低级解法的更多相关文章
- [leetcode]84.Largest Rectangle in Histogram ,O(n)解法剖析
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- LeetCode 84. Largest Rectangle in Histogram 单调栈应用
LeetCode 84. Largest Rectangle in Histogram 单调栈应用 leetcode+ 循环数组,求右边第一个大的数字 求一个数组中右边第一个比他大的数(单调栈 Lee ...
- leetcode之Largest Rectangle in Histogram
问题来源:Largest Rectangle in Histogram 问题描述:给定一个长度为n的直方图,我们可以在直方图高低不同的长方形之间画一个更大的长方形,求该长方形的最大面积.例如,给定下述 ...
- [LeetCode] Largest Rectangle in Histogram O(n) 解法详析, Maximal Rectangle
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- Java for LeetCode 084 Largest Rectangle in Histogram【HARD】
For example, Given height = [2,1,5,6,2,3], return 10. 解题思路: 参考Problem H: Largest Rectangle in a Hist ...
- [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- LeetCode之Largest Rectangle in Histogram浅析
首先上题目 Given n non-negative integers representing the histogram's bar height where the width of each ...
- [LeetCode OJ] Largest Rectangle in Histogram
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [LeetCode#84]Largest Rectangle in Histogram
Problem: Given n non-negative integers representing the histogram's bar height where the width of ea ...
随机推荐
- IOS开发之路三(XML解析之GDataXML的使用)
最近再做一个项目需要用到xml的解析.今天查了一些资料自己做了一个小demo.纯OC没有界面.. 在IOS平台上进行XML文档的解析有很多种方法,在SDK里面有自带的解析方法,但是大多情况下都倾向于用 ...
- 增加窗体边框3D效果
/// <summary> /// 增加窗体边框3D效果 /// </summary> /// <param name="e"></par ...
- ASP.NET MVC3开发 - CodeFisrt数据库篇之M层验证之调用远程方法(Remote)验证
本文讲述在作者在使用.net mvc3进行开发的时候用到的两种调用远程验证的方法,第一种方法比较傻瓜,第二种方法方便好用,调用远程验证是个比较常见的验证方法,比如注册用户时的用户名唯一性验证. 作者原 ...
- 纯Python综合图像处理小工具(3)10种滤镜算法
<背景> 滤镜处理是图像处理中一种非常常见的方法.比如photoshop中的滤镜效果,除了自带的滤镜,还扩展了很多第三方的滤镜效果插件,可以对图像做丰富多样的变换:很多手机app实现了实 ...
- STL迭代器与部分算法学习笔记
迭代器是类似指针的对象,分为5种,输入,输出,前向,双向和随机访问 输入迭代器(InputIterator) 输入迭代器并不是指某种类型,而是指一系列类型 举例 template<class I ...
- mysql基础:数据库的创建,增删改查
=============查看数据库========================== 使用SHOW语句找出服务器上当前存在什么数据库: mysql> SHOW DATABASES; +--- ...
- mssql分页原理及效率分析
下面是常用的分页,及其分页效率分析. 1.分页方案一:(利用Not In和SELECT TOP分页) 语句形式: SELECT TOP 10 * FROM TestTable WHERE (ID NO ...
- eclipse 导入 Maven 多模块项目
右键 --> Import --> Existing Maven Projects --> 项目目录 选中所有子模块 --> Delete(一定不要勾选Delete proje ...
- spring_boot打jar包及打包错误的解决方法
问题产生及解决 对于刚接手spring_boot的人,可能会感觉到很茫然无措,看到书上写的spring_boot是直接打包成jar包,使用java -jar *运行.然而却不知道该怎么打包.而创建sp ...
- C#:using与.net对象销毁
一 . 1.using 语句获取一个或多个资源,执行一个语句,然后处置该资源. 2.using 语句: using ( 资源获取 ) 嵌入语句 3.资源获取: 局部变量声明 表达式 资源是实现 ...