在学习期间,我偶然发现了一个有趣的问题而且我被困住了。
我们有一系列不同高度的矩形(每个矩形的基数为1),我们想要计算它们可以适合的最大矩形的面积。
附加我认为重新组合此问题的图像,我们想要找到红色矩形区域。
现在,我尚未参加DS课程,但我自己学到了一些知识,但我似乎无法找到任何快速解决方案。高度可以很大,比如百万大,以及矩形的总数。有人可以提供一些指导方针吗?
答案 0 :(得分:1)
好的,我有个主意。你呢:
作为优化,在某些时候,您可以计算出剩余的矩形在给定当前最低边界时不会超过最大面积。
注意,这不是确切的解决方案,因为你也可以从头开始丢弃任意数量的矩形,但我认为这是一个很好的通用方法。如果我有时间,会尝试延长它。
编辑:进一步了解它,但将上面的答案留作特别的"案例解决方案,因为它也很好。现在为实际的解决方案:
这应该是O(n2)最坏的情况(矩形按高度排序),但在一般情况下是O(NlogN)。当在分支的底部进行计算时,它将使用最多O(logN)内存。
由于问题的性质,不确定能否做得更好; - )
答案 1 :(得分:0)
这是一个简单的线性解决方案:
假设最低矩形的位置是固定的。那我们想做什么?好吧,我们想要找到左边和右边的距离,直到我们找到一个较低的矩形(让我们称之为L
和R
)。如果我们知道它们,我们可以将所有矩形的宽度从L
乘以R
乘以该矩形的高度并更新答案。
宽度很容易的部分:我们可以使用前缀和。
现在让我们在线性时间(总计)中找到位于给定位置右侧的最左下方矩形。以下是此部分的伪代码:
s = empty stack
L = new int[n]
fill(L, -1)
for i <- 0 ... n - 1
while !s.isEmpty() && s.peek().first >= h[i]
s.pop()
if !s.isEmpty()
L[i] = s.peek().second
s.push((h[i], i)
现在我们可以反转数组并为同一个R[i]
计算i
。
当我们有L
,R
和前缀sums时,我们可以迭代所有矩形来得到答案:
for i <- 0 ... n - 1
height = h[i]
width = getWidth(L[i], R[i]) // we use prefix sums in getWidth
res = max(res, height * width)
就是这样。