关于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 ...
随机推荐
- tomcat安装和基本配置
首先,默认电脑上已经配置好java环境. 在http://tomcat.apache.org/这里下载tomcat二进制版本,下载到本地后随意解压在某个盘, 我解压在D:\apache-tomcat- ...
- OSGI原形(.NET)
OSGI原形(.NET) 目前只做了基础的功能,比如: 各个模块单独的AppDomain容器 Activator激活 导出的服务检查 不过,虽说这样,但目前的这个版本已经能实现模块分离.互相依赖调用等 ...
- ThreadPool&ManualResetEvent
在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPool(线程池)来解决: 另一种情况:线程 ...
- SVN 在 Xcode中的状态说明
最近同事总是问我关于SVN状态的问题,‘C’是什么意思啦?‘A’是什么意思啦?等等一系列问题. 为了方便以后查阅,以及新同事的快速融入,特在此记录一下^_^. 当然了大家也可以google一下,一搜一 ...
- Mongodb 集群搭建以及常见错误
Mongodb 集群搭建以及常见错误 1 关于Replica Sets +Sharding(主从复制加分片)搭建,不这详细去说,网上有很多,大部分的例子就三台服务器之间做主从复制,分2个shard,架 ...
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
用字符数组方法: 基本思路是,先判断字符的结束标志'\0',然后从该位置向前输出. 实现代码: #include<iostream> using namespace std; int ma ...
- Java 在本地文件中查找固定字符串
适用范围:只适用于在文本文档中查找(如,txt.java.c等等,并不适用与doc.xls等等这些文件),可嵌套文件夹.但是对中文不支持. 例如:文件夹:F:/demo 子文件夹:F:/demo/er ...
- samba安装与配置
1.安装软件包rpm -q samba samba-common samba-client cifs-utilsyum -y install samba samba-common samba-clie ...
- Java核心技术 卷Ⅰ 基础知识(1)
第三章 Java的基本程序设计结构 Java对大小写敏感 命名规范为骆驼命名法,不能使用保留字 main方法必须声明为public 如果main方法正常退出,java应用程序的退出代码为0,表示成功运 ...
- NUTZ中处理系统未捕获异常
关键内容 mvc-chain.js ViewProcessor ai.setFailView(“redirect:/sysError.html”); log.error(this.trrowableT ...