鱼C论坛

 找回密码
 立即注册
查看: 2690|回复: 23

[已解决]求最大矩形面积

[复制链接]
发表于 2019-11-19 17:10:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Stubborn 于 2019-12-2 05:28 编辑
给定 n 个非负整数,用来表示`柱子`的高度。每个柱子彼此相邻,且宽度为 1

输入: [2,1,5,6,2,3]
输出: 10
histogram_area.png

有大的数组[x for x in rang(20000) ] ,所以尽可能的吧时间复杂度降低到 O(n^2)以下



图解:





xin.png




代码实现:


  1. class Solution:
  2.     def largestRectangleArea(self, heights: List[int]) -> int:
  3.         if len(heights) == 1: return heights[0]
  4.         heights.append(0)
  5.         stack = [0, ]
  6.         length = len(heights)
  7.         result = 0

  8.         for h in range(1, length):
  9.             if heights[stack[-1]] < heights[h]:
  10.                 stack.append(h)
  11.             else:
  12.                 while heights[stack[-1]] >= heights[h]:
  13.                     s = stack.pop()
  14.                     if not stack:
  15.                         S = h * heights[s]
  16.                         if S > result: result = S
  17.                         stack.append(h)
  18.                         break

  19.                     S = (h - stack[-1] - 1) * heights[s]

  20.                     if S > result: result = S
  21.                     if heights[stack[-1]] < heights[h]:
  22.                         stack.append(h)
  23.                         break

  24.         return result
复制代码

最佳答案
2019-11-21 14:24:29
  1. class Solution:
  2.     def largestRectangleArea(self, heights: List[int]) -> int:
  3.         res=0
  4.         numdict = []
  5.         for i in heights:
  6.             if numdict==[]:
  7.                 numdict.append(i)
  8.             elif i >= numdict[-1]:
  9.                 numdict.append(i)
  10.             else:
  11.                 t = 0
  12.                 for l in range(len(numdict)-1,-1,-1):
  13.                     if numdict[l]>i:
  14.                         t=t+1
  15.                         res=max(res,numdict[l]*t)
  16.                     else:
  17.                         break
  18.                 numdict = numdict[:-t]+(t+1)*[i]
  19.         for i in set(numdict):
  20.             res =max(res,i*(len(numdict)-numdict.index(i)))
  21.         return res
复制代码


写了一个通过边缘的.....
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-19 18:43:35 From FishC Mobile | 显示全部楼层
咋净研究算法,狠♂呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 18:08:42 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-11-20 18:14 编辑

真好玩儿^_^
  1. from typing import List

  2. def MaxRectangle(heights:List[int]) -> int:
  3.     m_area = 0
  4.     for h in range(max(heights),0,-1):
  5.         area = 0
  6.         for each in heights:
  7.             if each < h:
  8.                 m_area = max(area,m_area)
  9.                 area = 0
  10.             else:
  11.                 area += h
  12.     return m_area
复制代码

小小地改动一下:
  1. from typing import List

  2. def MaxRectangle(heights:List[int]) -> int:
  3.     m_area = len(heights)
  4.     for h in range(max(heights),1,-1):
  5.         area = 0
  6.         for each in heights:
  7.             if each < h:
  8.                 m_area = max(area,m_area)
  9.                 area = 0
  10.             else:
  11.                 area += h
  12.     return m_area
复制代码


评分

参与人数 1荣誉 +1 鱼币 +2 贡献 +1 收起 理由
Stubborn + 1 + 2 + 1 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 18:59:46 | 显示全部楼层
本帖最后由 danteer 于 2019-11-20 19:08 编辑
  1. def func(list1):
  2.     result = []
  3.     for i in range(min(list1),max(list1)+1):
  4.         indexlist = []
  5.         for each in range(len(list1)):
  6.             if list1[each] == i:
  7.                 indexlist.append(each)
  8.         right = -1
  9.         for each in indexlist:
  10.             if each <= right:
  11.                 continue
  12.             left = each - 1
  13.             right = each + 1
  14.             while left > -1:
  15.                 if list1[left] >= list1[each]:
  16.                     left -= 1
  17.                 else:
  18.                     left += 1
  19.                     break
  20.             if left == -1:
  21.                 left = 0
  22.             while right < len(list1):
  23.                 if list1[right] >= list1[each]:
  24.                     right += 1
  25.                 else:
  26.                     right -= 1
  27.                     break
  28.             if right == len(list1):
  29.                 right -= 1
  30.             result.append(list1[each]*(right-left+1))
  31.     return max(result)
复制代码

评分

参与人数 1荣誉 +1 鱼币 +2 贡献 +1 收起 理由
Stubborn + 1 + 2 + 1 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 19:52:15 | 显示全部楼层
  1. [0,0,0,0,0,0,0,0,2147483647]
复制代码


超时了~  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 19:54:03 | 显示全部楼层
阴阳神万物主 发表于 2019-11-20 18:08
真好玩儿^_^

小小地改动一下:

数组会出现 0 表示没有高度,宽度为1,原来的题目也没有说,测试才发现,会分治嘛,教教我呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 19:56:41 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-11-20 20:03 编辑
Stubborn 发表于 2019-11-20 19:54
数组会出现 0 表示没有高度,宽度为1,原来的题目也没有说,测试才发现,会分治嘛,教教我呀


啊哈,我没系统地学过算法。
我也并没有考虑有高度为 0 的情况,我想的是高度至少为1 …… 如果说真的碰上那样的数据,算瞎猫碰着死耗子了。
根据矩形的面积公式,有一边长度为零,那么面积应该为 0 啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 20:03:31 | 显示全部楼层
阴阳神万物主 发表于 2019-11-20 19:56
啊哈,我没系统地学过算法。

决定最大矩形的面积,总是最小值决定的。代码还没有写出来

#  [2,1,5,6,2,3] -> 6 * 1 = 6
#   [2] -> 2        [5,6,2,3] -> 2*4 = 8
#               [5,6]->2*5 =  10  [3]-> 3
#               5,6 -> 5,6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:06:24 | 显示全部楼层
Stubborn 发表于 2019-11-20 20:03
决定最大矩形的面积,总是最小值决定的。代码还没有写出来

#  [2,1,5,6,2,3] -> 6 * 1 = 6
...

感觉跟短板效应有点儿像啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:07:34 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-11-20 20:11 编辑
Stubborn 发表于 2019-11-20 20:03
决定最大矩形的面积,总是最小值决定的。代码还没有写出来

#  [2,1,5,6,2,3] -> 6 * 1 = 6
...

既然是这样,那可就更好办了
  1. from typing import List

  2. def MaxRectangle(heights:List[int]) -> int:
  3.     m_area = 0
  4.     le = len(heights)
  5.     for l in range(le):
  6.         for r in range(l+1,le+1):
  7.             m_area = max(m_area,min(heights[l:r])*(r-l))
  8.     return m_area
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 20:14:32 | 显示全部楼层
阴阳神万物主 发表于 2019-11-20 20:07
既然是这样,那可就更好办了

数组太长,超时了~   GO
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:16:57 | 显示全部楼层
  1. def func(list1):
  2.     result = []
  3.     for i in set(list1):
  4.         indexlist = []
  5.         for each in range(len(list1)):
  6.             if list1[each] == i:
  7.                 indexlist.append(each)
  8.         right = -1
  9.         for each in indexlist:
  10.             if each <= right:
  11.                 continue
  12.             left = each - 1
  13.             right = each + 1
  14.             while left > -1:
  15.                 if list1[left] >= list1[each]:
  16.                     left -= 1
  17.                 else:
  18.                     left += 1
  19.                     break
  20.             if left == -1:
  21.                 left = 0
  22.             while right < len(list1):
  23.                 if list1[right] >= list1[each]:
  24.                     right += 1
  25.                 else:
  26.                     right -= 1
  27.                     break
  28.             if right == len(list1):
  29.                 right -= 1
  30.             result.append(list1[each]*(right-left+1))
  31.     return max(result)
复制代码
换个set就能继续暴力破解了,不过dp还是不会弄
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:21:19 | 显示全部楼层
Stubborn 发表于 2019-11-20 20:14
数组太长,超时了~   GO

也就是我一开始那个可以是吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:22:26 | 显示全部楼层
本帖最后由 danteer 于 2019-11-20 20:28 编辑
  1. def func(heights):
  2.     result = []
  3.     for i in set(heights):
  4.         indexlist = []
  5.         for each in range(len(heights)):
  6.             if heights[each] == i:
  7.                 indexlist.append(each)
  8.         right = -1
  9.         for each in indexlist:
  10.             if each <= right:
  11.                 continue
  12.             left = each - 1
  13.             right = each + 1
  14.             while left > -1:
  15.                 if heights[left] >= heights[each]:
  16.                     left -= 1
  17.                 else:
  18.                     left += 1
  19.                     break
  20.             if left == -1:
  21.                 left = 0
  22.             while right < len(heights):
  23.                 if heights[right] >= heights[each]:
  24.                     right += 1
  25.                 else:
  26.                     right -= 1
  27.                     break
  28.             if right == len(heights):
  29.                 right -= 1
  30.             result.append(heights[each]*(right-left+1))
  31.     return max(result)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:28:04 | 显示全部楼层
Stubborn 发表于 2019-11-20 20:14
数组太长,超时了~   GO

咱一开始那个,时间复杂度为 O(n) ,后来这个是 O((n^2)!) 可不是天壤之别吗,只是看着简单而已
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 20:37:59 | 显示全部楼层
阴阳神万物主 发表于 2019-11-20 20:28
咱一开始那个,时间复杂度为 O(n) ,后来这个是 O((n^2)!) 可不是天壤之别吗,只是看着简单而已

处理下 数组出现0的情况,0 表示没有高度等于0,宽度为1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 20:41:18 | 显示全部楼层

超时了,数组长度很长的时候,需要数据吗?  原题链接
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 20:50:18 | 显示全部楼层
Stubborn 发表于 2019-11-20 20:41
超时了,数组长度很长的时候,需要数据吗?  原题链接

看到了,1到19999
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-20 21:16:40 | 显示全部楼层

这个用分治
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 21:42:39 | 显示全部楼层
Stubborn 发表于 2019-11-20 20:37
处理下 数组出现0的情况,0 表示没有高度等于0,宽度为1

好家伙,你看这样行不?
  1. from typing import List

  2. def MaxRectangle(heights:List[int]) -> int:
  3.     m_area = 0
  4.     for h in range(max(heights),0,-1):
  5.         area = 0
  6.         for each in heights:
  7.             if each < h:
  8.                 m_area = max(area,m_area)
  9.                 area = 0
  10.             else:
  11.                 area += h
  12.         m_area = max(area,m_area)
  13.     return m_area

  14. if __name__ == '__main__':
  15.     print('10 输出',MaxRectangle([2,1,5,6,2,3]))
  16.     print('0 输出',MaxRectangle([0,0,0,0]))
  17.     print('1 输出',MaxRectangle([0,0,0,1]))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 12:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表