JAVA算法练习题day64
73.柱状图中最大的矩形
计算矩形面积需要它的高和宽,枚举其一,是暴力法。
暴力,枚举宽:
class Solution(object):def largestRectangleArea(self, heights):""":type heights: List[int]:rtype: int"""ans = 0#暴力:扫描过程中记录当前高度 min() 与ans max() 计算即可o(n^2)for i in range(len(heights)):h = heights[i]ans = max(ans,heights[i])for j in range(i+1,len(heights)):h = min(h,heights[j])ans = max((j-i+1)*h,ans)return ans
暴力,枚举高:
class Solution(object):def largestRectangleArea(self, heights):""":type heights: List[int]:rtype: int"""#枚举高的暴力做法,第一次见这种做法,学会它#使用一重循环枚举某一根柱子,将其固定为矩形的高度 h。随后我们从这跟柱子开始向两侧延伸,直到遇到高度小于 h 的柱子,就确定了矩形的左右边界。如果左右边界之间的宽度为 w,那么对应的面积为 w×hans = 0for mid in range(len(heights)):h = heights[mid]left ,right = mid,midwhile left-1>=0 and heights[left-1]>=h:left-=1while right+1<len(heights) and heights[right+1]>=h:right+=1ans = max((right-left+1)*h,ans)return ans

用单调栈来实现上述思路。

规则3可能看不懂,解释如下: 3 6 8 遇到5。8出栈,元素5是8向右找第一个比他小的元素;出栈一次后,显然当前栈顶元素6是8向左找第一个比它小的元素。这样就找到了栈顶元素朝左朝右分别第一个比它小的元素。那么:依旧是遍历高度,使用单调栈,在出栈操作时得到前后边界,并计算面积。

又搞错了,python if not nums是空判断(空则返回-1 。not-1就是True)。容易和 !nums.empty() 弄混。
class Solution(object):def largestRectangleArea(self, heights):""":type heights: List[int]:rtype: int"""stk = [] # 单调栈,存储柱子的索引,维护递增顺序ans = 0n = len(heights)# 遍历每个柱子,确定右边界并计算面积for i in range(n):# 当栈不为空且当前柱子高度小于栈顶柱子高度时,弹出栈顶并计算面积while stk and heights[stk[-1]] > heights[i]:mid = stk.pop() # 弹出的栈顶元素为当前计算的柱子索引# 确定左边界:栈为空则左侧无更矮柱子(左边界为-1),否则为新栈顶left = -1 if not stk else stk[-1]#注意:面积不算左右两边的矮柱子,并且以自己为高度,因为自己是所形成矩形里面最矮的# 面积 = 高度(当前柱子高度) * 宽度(右边界i - 左边界left - 1)current_area = heights[mid] * (i - left - 1)ans = max(ans, current_area)
#别忘了给元素入栈stk.append(i) # 当前柱子索引入栈# **处理栈中剩余元素(这些元素右侧无更矮柱子,右边界为n)**while stk:mid = stk.pop()left = -1 if not stk else stk[-1]current_area = heights[mid] * (n - left - 1)ans = max(ans, current_area)return ans
